

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.png">
  <link rel="icon" href="/img/favicon.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="John Doe">
  <meta name="keywords" content="">
  
    <meta name="description" content="这是一个java基础课程学习记录. JAVA java基础 跨平台，解释型 所有变量、方法、类名：见名知义 类成员变量：首字母小写和驼峰原则：monthSalary 局部变量：首字母小写和驼峰原则 常量：大写字母和下划线：MAX _VALUE 类名：首字母大写和驼峰原则：Man,GoodMan 方法名：首字母小写和驼峰原则：runO,runRun(0 整数默认int类型: lon">
<meta property="og:type" content="article">
<meta property="og:title" content="java基础">
<meta property="og:url" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="这是一个java基础课程学习记录. JAVA java基础 跨平台，解释型 所有变量、方法、类名：见名知义 类成员变量：首字母小写和驼峰原则：monthSalary 局部变量：首字母小写和驼峰原则 常量：大写字母和下划线：MAX _VALUE 类名：首字母大写和驼峰原则：Man,GoodMan 方法名：首字母小写和驼峰原则：runO,runRun(0 整数默认int类型: lon">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220414191342707.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220416144955468.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220425105730336.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220425105950636.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220425201738284.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/JAVA基础/image-20220426143136185.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220426143547400.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220426154833924.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/JAVA基础/image-20220427193401207.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220428190902198.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429095931746.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429100034115.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429103304035.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429104602782.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429161856082.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429162504314.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429165534998.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429174326693.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429174340243.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429203603902.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430093310743.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430094241610.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430164907424.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430170214454.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430171323459-165154597765923.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430192519797-165154600613126.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220501180353162-165154601918229.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220501182543306-165154603584732.png">
<meta property="og:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220501182605641-165154605152335.png">
<meta property="article:published_time" content="2022-05-04T16:00:00.000Z">
<meta property="article:modified_time" content="2022-05-05T08:18:24.842Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="基础">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="http://example.com/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220414191342707.png">
  
  
  <title>java基础 - Hexo</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4/github-markdown.min.css" />
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hint.css@2/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.css" />
  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.8.14","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 6.1.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>s.un的藏书阁</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/ying.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="java基础">
              
            </span>

            
              <div class="mt-3">
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2022-05-05 00:00" pubdate>
        2022年5月5日 凌晨
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      130k 字
    </span>
  

  
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      1084 分钟
    </span>
  

  
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">java基础</h1>
            
            <div class="markdown-body">
              <p>这是一个java基础课程学习记录.</p>
<h1 id="java">JAVA</h1>
<h2 id="java基础">java基础</h2>
<h6 id="跨平台解释型"><strong>跨平台，解释型</strong></h6>
<p>所有变量、方法、类名：见名知义
类成员变量：首字母小写和驼峰原则：monthSalary
局部变量：首字母小写和驼峰原则 常量：大写字母和下划线：MAX _VALUE
类名：首字母大写和驼峰原则：Man,GoodMan
方法名：首字母小写和驼峰原则：runO,runRun(0</p>
<p>整数默认int类型: long a = 2L;</p>
<p>小数默认double：float a = 1.2F;</p>
<p>boolean：只能赋值true，false</p>
<h6 id="位运算"><strong>位运算</strong>：</h6>
<p>1、&amp;和&amp;&amp;：与，短路与</p>
<p>2、|和||：或，短路或</p>
<h6 id="字符串连接符"><strong>字符串连接符</strong>：+</h6>
<p>通过String，+变为字符串连接符。</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220414191342707.png" srcset="/img/loading.gif" lazyload class="">
<p>特例：整形常量为int，可自动转化为byte/short/char，前提为不越界</p>
<h6 id="方法函数"><strong>方法</strong>：函数</h6>
<h6 id="内存管理"><strong>内存管理</strong></h6>
<p>Java的内存管理很大程度就是：堆中对象的管理，其中包括对象空间的分配和释放。
对象空间的分配：使用new关键字创建对象即可
对象空间的释放：将对象赋值null即可。</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220416144955468.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="jvm调优和full-gc"><strong>JVM调优和Full GC</strong></h6>
<p>在对JVM调优的过程中，很大一部分工作就是对于FuLL
GC的调节。有如下原因可能</p>
<h6 id="导致full-gc"><strong>导致Full GC:</strong></h6>
<p>1.年老代(Tenured)被写满 2.永久代(Perm)被写满
3.System.gc0\()被显式调用 4.上一次GC之后Heap的各域分配策略动态变化</p>
<h6 id="this"><strong>this</strong></h6>
<p>1、this()调用重载的构造方法，避免相同的初始化代码。但只能在构造方法中用，并且必须位于构造方法的第一句。</p>
<p>xzs();{}</p>
<p>xzs(int a){</p>
<p>this();//调用xzs();{}</p>
<p>this.a=a;</p>
<p>}</p>
<p>2、this不能用于static方法中。
3、this是作为普通方法的“隐式参数”，由系统传入到方法中。</p>
<h6 id="包机制packageimport"><strong>包机制package、import</strong></h6>
<p>包(（package)相当于文件夹对于文件的作用。用于管理类、用于解决类的重名问题。</p>
<h6 id="package"><strong>package</strong></h6>
<p>package的使用有两个要点： 1.通常是类的第一句非注释性语句。
2.包名：域名倒着写即可，再加上模块名，便于内部管理类。com.xzs.aa</p>
<h6 id="导入类import"><strong>导入类import</strong></h6>
<p>如果要使用其他包的类，需使用import,从而在本类中直接通过类名来调用，否则就需要书写类的完整包名和类名。</p>
<p>import java.util.* //导入所有类，降低编译速度，不会降低运行速度</p>
<h6 id="继承"><strong>继承</strong></h6>
<p>extends</p>
<h6 id="组合"><strong>组合</strong></h6>
<p>在子类创建父类对象，使用父类属性</p>
<h6 id="super"><strong>super</strong></h6>
<p>调用父类方法，父类被覆盖了，但依然存在。</p>
<h6 id="静态代码块"><strong>静态代码块</strong>：</h6>
<p>static{}；属于类，优先加载。一般用于初始化静态资源。比如扑克牌类：优先定义54张牌的静态集合。</p>
<h6 id="静态工具类"><strong>静态工具类</strong>：</h6>
<p>使用static定义一系列方法，供大家使用，建议私有化，不用其创建对象。</p>
<h6 id="设计模式"><strong>设计模式</strong>：</h6>
<p>开发中经常遇到一些问题，一个问题通常有种解法的，但其中肯定有一种解法是最优的，这个最优的解法被人总结出来了，称之为设计模式。</p>
<h6 id="单例模式"><strong>单例模式</strong>：</h6>
<p>可以保证系统中，应用该模式的这个类永远只有一个实例，即一个类永远只能创建一个对象。
例如任务管理器对象我们只需要一个就可以解决问题了，这样可以节省内存空间。<strong>设计步骤：</strong>定义一个类，把构造器私有。定义一个静态变量存储一个对象。</p>
<p>`饿汉单例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></div></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">SingleInstance</span>&#123;`<br><br>​	`<span class="hljs-comment">//2、提供储存地址`</span><br><br>​	`<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">SingleInstance</span> <span class="hljs-variable">instance</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SIngleInstance</span>();`<br><br>​	`<span class="hljs-comment">//1、构造器私有化`</span><br><br>​	`<span class="hljs-keyword">private</span> <span class="hljs-title function_">SingleInstance</span><span class="hljs-params">()</span>&#123;&#125;`<br><br>`&#125;`<br></code></pre></td></tr></table></figure>
<h6 id="懒汉单例"><strong>懒汉单例</strong></h6>
<p>1、定义一个类，把构造器私有。 2、定义一个静态变量存储一个对象。
3、提供一个返回单例对象的方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">SingleInstance</span>&#123;`<br><br>`<span class="hljs-comment">//2、提供储存地址`</span><br><br>`<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">SingleInstance</span> <span class="hljs-variable">instance</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br><br><span class="hljs-comment">//3、提供一个方法`</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> SingleInstance <span class="hljs-title function_">getInstance</span><span class="hljs-params">()</span>&#123;<br>	<span class="hljs-keyword">if</span>(instance==<span class="hljs-literal">null</span>)<br>		instance = <span class="hljs-keyword">new</span> <span class="hljs-title class_">SingleInstance</span>();<br>	<span class="hljs-keyword">return</span> instance;<br>&#125;<br><br>`<span class="hljs-comment">//1、构造器私有化`</span><br><br>`<span class="hljs-keyword">private</span> <span class="hljs-title function_">SingleInstance</span><span class="hljs-params">()</span>&#123;&#125;`<br><br>`&#125;`<br></code></pre></td></tr></table></figure>
<h6 id="继承的特点"><strong>继承的特点</strong></h6>
<p>①子类可以继承父类的属性和行为，但是子类不能继承父类的构造器。
②Java是单继承模式：一个类只能继承一个直接父类。
③Java不支持多继承、但是支持多层继承。
④Java中所有的类都是Object类的子类。</p>
<h6
id="子类继承父类后构造器的特点"><strong>子类继承父类后构造器的特点：</strong></h6>
<p>子类中所有的构造器默认都会先访问父类中无参的构造器，再执行自己。</p>
<h6 id="finall的作用"><strong>finall的作用</strong></h6>
<p>final关键字是最终的意思，可以修饰(类、方法、变量)
修饰类：表明该类是最终类，不能被继承。
修饰方法：表明该方法是最终方法，不能被重写。
修饰变量：表示该变量第一次赋值后，不能再次被赋值（有且仅能被赋值一次）。</p>
<h6 id="枚举的特征"><strong>枚举的特征：</strong></h6>
<p>枚举类都是继承了枚举类型：java.lang.Enum
枚举都是最终类，不可以被继承。
构造器的构造器都是私有的，枚举对外不能创建对象。
枚举类的第一行默认都是罗列枚举对象的名称的。
枚举类相当于是多例模式。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> <span class="hljs-title class_">Season</span>&#123;<br> SPRING,SUMER,AUTUMN,WINTER;<br>&#125;<br>Season k;<br>SWITCh(k)&#123;<br>	<span class="hljs-keyword">case</span> SPRING:<br>	<span class="hljs-keyword">case</span> SUMER:<br>	<span class="hljs-keyword">case</span> AUTUMN:<br>	<span class="hljs-keyword">case</span> WINTER:<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="模板方法">模板方法：</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span>&#123;<br>	<span class="hljs-comment">//声明模板方法,建议用final修饰</span><br>	<span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">write</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;我的爸爸&quot;</span>);<br>        System.out.println(wrtiemain());<br>        System.out.println(<span class="hljs-string">&quot;他真牛逼&quot;</span>);<br>	&#125;<br>	<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-title function_">writemain</span><span class="hljs-params">()</span>&#123;<br>		 System.out.println(<span class="hljs-string">&quot;&quot;</span>);<br>	&#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="接口">接口:</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">Demo</span>&#123;<br>	<span class="hljs-comment">//1、常量</span><br>	<span class="hljs-type">String</span> <span class="hljs-variable">SCHOOL_NAME</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;xzs&quot;</span><br>	<span class="hljs-comment">//public static final String SCHOOL_NAME</span><br>	<span class="hljs-comment">//2、抽象方法</span><br>	<span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span>;<br>	<span class="hljs-comment">//public abstract void run();</span><br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="接口实现">接口实现：</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">man</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Demo</span>&#123;<br>	<br>&#125;<br></code></pre></td></tr></table></figure>
<p>JDK8开始后新增了那些方法？ 默认方法：default修饰，实现类对象调用。
静态方法：static修饰，必须用当前接口名调用
私有方法：private修饰，jdk9开始才有的，只能在接口内部被调用。</p>
<h6 id="接口的注意事项">接口的注意事项</h6>
<p>1、接口<strong>不能创建对象</strong>。
2、一个类实现多个接口，多个接口中有<strong>同样的静态方法</strong>不冲突。
3、一个类继承了父类，同时又实现了接口，父类中和接口中有同名方法，<strong>默认用父类的</strong>。
4、一个类实现了多个接口，多个接口中存在同名的默认方法，不冲突，<strong>这个类重写该方法即可</strong>。
5、一个接口继承多个接口，是没有问题的，如果多个接口中存在规范冲突则不能多继承。</p>
<h6 id="多态">多态：</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//Animal 父类 run();方法</span><br><span class="hljs-comment">//dog 子类 wang();方法独有</span><br><span class="hljs-comment">//cat 子类 miao();方法独有</span><br><span class="hljs-type">Animal</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">dog</span>();<br><span class="hljs-type">Animal</span> <span class="hljs-variable">b</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">cat</span>();<br><span class="hljs-comment">//多态展示</span><br>a.run();<span class="hljs-comment">//狗跑</span><br>b.run();<span class="hljs-comment">//猫跑</span><br><span class="hljs-comment">//a.wang();出错</span><br><span class="hljs-type">dog</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span>(dog) a;<br>c.wang();<span class="hljs-comment">//正确，没有创建新对象，c不是新对象</span><br><span class="hljs-comment">//建议用法</span><br><span class="hljs-keyword">if</span> (a <span class="hljs-keyword">instanceof</span> dog)&#123;<br>	<span class="hljs-type">dog</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span>(dog) a;<br>	c.wang();<br>&#125;<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(a <span class="hljs-keyword">instanceof</span> cat)&#123;<br>	<span class="hljs-type">cat</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span>(cat) a;<br>	c.miao();<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="内部类">内部类</h4>
<p>·内部类就是定义在一个类里面的类，里面的类可以理解成（寄生），外部类可以理解成（宿主）。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">People</span>&#123;<br><span class="hljs-comment">//内部类</span><br>	<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Heart</span>&#123;<br>	&#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>内部类的使用场景、作用</strong>
当一个事物的内部，还有一个部分需要一个完整的结构进行描述，而这个内部的完整的结构又只为外部事物提供服务，那么整个内部的完整结构可以选择使用内部类来设计。
内部类通常可以方便访问外部类的成员，包括私有的成员。
内部类提供了更好的封装性，内部类本身就可以用private
protectecd等修饰，封装性可以做更多控制。</p>
<h6
id="静态内部类用static修饰">1、<strong>静态内部类</strong>（用static修饰）</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs JAVA">Outer.<span class="hljs-type">inner</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Outer</span>.inner(); <br></code></pre></td></tr></table></figure>
<h6
id="成员内部类无static">2、<strong>成员内部类</strong>（无static）</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs JAVA">Outer.<span class="hljs-type">inner</span> <span class="hljs-variable">in</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Outer</span>().<span class="hljs-keyword">new</span> <span class="hljs-title class_">inner</span>();<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">class</span> <span class="hljs-title class_">People</span>&#123;<br>	<span class="hljs-keyword">private</span> <span class="hljs-type">int</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> <span class="hljs-number">150</span>;<br>	<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Heart</span>&#123;<br>        <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> <span class="hljs-variable">b</span> <span class="hljs-operator">=</span> <span class="hljs-number">110</span>;<br>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">show</span><span class="hljs-params">()</span>&#123;<br>          <span class="hljs-type">int</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> <span class="hljs-number">78</span>;<br>          System.out.println(c);<br>          System.out.println(<span class="hljs-built_in">this</span>.b);<br>          System.out.println(People.<span class="hljs-built_in">this</span>.a);<br>		&#125;<br>    &#125;<br>	<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="局部内部类">3、<strong>局部内部类</strong></h6>
<h6 id="匿名内部类">4、<strong>匿名内部类</strong>*</h6>
<p>​ 本质上是一个没有名字的局部内部类，定义在方法中、代码块中、等。</p>
<p>​ 作用：方便创建子类对象，最终目的为了简化代码编写。</p>
<p>匿名内部类是一个没有名字的内部类。
匿名内部类写出来就会产生一个匿名内部类的对象。
匿名内部类的对象类型相当于是当前new的那个的类型的子类类型。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">new</span> 类|抽象类名|或者接口名（）&#123;<br>重写方法；<br>&#125;;<br><br><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Animal</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span>;<br>&#125;<br>main&#123;<br>    <span class="hljs-type">Animal</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Animal</span>()&#123;<br>        <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span>&#123;<br>            Systerm.out.println(<span class="hljs-string">&quot;老虎会跑&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="bigdecimal">BigDecimal:</h4>
<p>解决浮点数精度失真问题</p>
<p>使用步骤 创建对象BigDecimal封装浮点型数据（最好的方式是调用方法）</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/*public static BigDecimal valueOf(double val) &#123;</span><br><span class="hljs-comment">        // Reminder: a zero double returns &#x27;0.0&#x27;, so we cannot fastpath</span><br><span class="hljs-comment">        // to use the constant ZERO.  This might be important enough to</span><br><span class="hljs-comment">        // justify a factory approach, a cache, or a few private</span><br><span class="hljs-comment">        // constants, later.</span><br><span class="hljs-comment">        return new BigDecimal(Double.toString(val));</span><br><span class="hljs-comment">        &#125;*/</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">test_BigDecimal</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">BigDecimal</span> <span class="hljs-variable">a1</span> <span class="hljs-operator">=</span> BigDecimal.valueOf(<span class="hljs-number">0.1</span>);<br>        <span class="hljs-type">BigDecimal</span> <span class="hljs-variable">a2</span> <span class="hljs-operator">=</span> BigDecimal.valueOf(<span class="hljs-number">0.2</span>);<br>        System.out.println(a1.add(a2));<br>        System.out.println(a1.subtract(a2));<br>        System.out.println(a1.multiply(a2));<br>        System.out.println(a1.divide(a2));<br>        <span class="hljs-comment">//转换为double传给别人</span><br>        <span class="hljs-type">double</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> a1.doubleValue();<br>        System.out.println(rs);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="日期与时间">日期与时间</h4>
<h6 id="date类">Date类</h6>
<p>Date类的对象在ava中代表的是当前所在系统的此刻日期时间。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">//计算当前时间121毫秒后时间</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">date</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Date</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>();<br>        System.out.println(a);<br>        <span class="hljs-type">long</span> <span class="hljs-variable">time</span> <span class="hljs-operator">=</span> a.getTime();<br>        System.out.println(time);<br>        <span class="hljs-type">Date</span> <span class="hljs-variable">d1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>();<br>        System.out.println(d1);<br>        <span class="hljs-type">long</span> <span class="hljs-variable">time2</span> <span class="hljs-operator">=</span>System.currentTimeMillis();<br>        time2 += (<span class="hljs-number">60</span> * <span class="hljs-number">60</span> + <span class="hljs-number">121</span>) * <span class="hljs-number">1000</span>;<br>        <span class="hljs-type">Date</span> <span class="hljs-variable">d2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>(time2);<br>        System.out.println(d2);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="simpledateformat类">simpleDateFormat类</h6>
<p>可以对Date对象或时间毫秒值格式化成我们喜欢的时间形式。
也可以把字符串的时间形式解析成日期对象。</p>
<p>1、格式化</p>
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<thead>
<tr class="header">
<th>Sun Apr 24 15:17:16 CST 2022<br/>2022年04月24日 15:17:16 星期日
下午<br/>2022年04月24日 15:19:17 星期日 下午</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">simpleDateFormat</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">//日期对象</span><br>        <span class="hljs-type">Date</span> <span class="hljs-variable">d</span> <span class="hljs-operator">=</span><span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>();<br>        System.out.println(d);<br>        <span class="hljs-comment">//格式</span><br>        <span class="hljs-type">SimpleDateFormat</span> <span class="hljs-variable">sdf</span> <span class="hljs-operator">=</span><span class="hljs-keyword">new</span> <span class="hljs-title class_">SimpleDateFormat</span>(<span class="hljs-string">&quot;yyyy年MM月dd日 HH:mm:ss EEE a&quot;</span>);<br>        <span class="hljs-comment">//格式化</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> sdf.format(d);<br>        System.out.println(rs);<br>        <span class="hljs-comment">//毫秒</span><br>        <span class="hljs-type">long</span> <span class="hljs-variable">time1</span> <span class="hljs-operator">=</span>System.currentTimeMillis() +<span class="hljs-number">121</span>*<span class="hljs-number">1000</span>;<br>        <span class="hljs-type">String</span>  <span class="hljs-variable">rs2</span> <span class="hljs-operator">=</span> sdf.format(time1);<br>        System.out.println(rs2);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>2、解析</p>
<p>请计算出2021年08月06日11点11分11秒，往后走2天14小时49分06秒后的时间是多少。</p>
<table>
<thead>
<tr class="header">
<th>2021年08月09日 02:00:17</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">simpleDateFormat2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> ParseException &#123;<br>        <span class="hljs-type">String</span> <span class="hljs-variable">dateStr</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;2021年08月06日 11:11:11&quot;</span>;<br>        <span class="hljs-type">SimpleDateFormat</span> <span class="hljs-variable">sdf</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SimpleDateFormat</span>(<span class="hljs-string">&quot;yyyy年MM月dd日 HH:mm:ss&quot;</span>);<br>        <span class="hljs-type">Date</span> <span class="hljs-variable">d</span> <span class="hljs-operator">=</span> sdf.parse(dateStr);<br>        <span class="hljs-type">long</span> <span class="hljs-variable">time</span> <span class="hljs-operator">=</span>d.getTime()+(<span class="hljs-number">2L</span>*<span class="hljs-number">24</span>*<span class="hljs-number">60</span>*<span class="hljs-number">60</span> +<span class="hljs-number">14</span>*<span class="hljs-number">60</span>*<span class="hljs-number">60</span> +<span class="hljs-number">49</span>*<span class="hljs-number">60</span> +<span class="hljs-number">6</span>)*<span class="hljs-number">1000</span>;<br>        System.out.println(sdf.format(time));<br>    &#125;<br></code></pre></td></tr></table></figure>
<h6 id="calendar类">Calendar类</h6>
<p>Calendar代表了系统此刻日期对应的日历对象。
Calendar是一个抽象类，不能直接创建对象。</p>
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<thead>
<tr class="header">
<th>java.util.GregorianCalendar[time=1650786277579,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=3,WEEK_OF_YEAR=18,WEEK_OF_MONTH=5,DAY_OF_MONTH=24,DAY_OF_YEAR=114,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=3,HOUR_OF_DAY=15,MINUTE=44,SECOND=37,MILLISECOND=579,ZONE_OFFSET=28800000,DST_OFFSET=0]<br/>2022<br/>4<br/>24<br/>Fri
Apr 29 15:44:37 CST 2022<br/><br/></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Canlendar</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">//1、拿到系统此时的日历对象</span><br>        <span class="hljs-type">Calendar</span> <span class="hljs-variable">cal</span> <span class="hljs-operator">=</span> Calendar.getInstance();<br>        System.out.println(cal);<br>        <span class="hljs-comment">//2、获取日历信息</span><br>        <span class="hljs-type">int</span> <span class="hljs-variable">year</span> <span class="hljs-operator">=</span> cal.get(Calendar.YEAR);<br>        System.out.println(year);<br>        <span class="hljs-type">int</span> <span class="hljs-variable">month</span> <span class="hljs-operator">=</span>cal.get(Calendar.MONTH)+<span class="hljs-number">1</span>;<br>        System.out.println(month);<br>        <span class="hljs-type">int</span> <span class="hljs-variable">day</span> <span class="hljs-operator">=</span> cal.get(Calendar.DAY_OF_MONTH);<br>        System.out.println(day);<br>        <span class="hljs-comment">//3、修改时间</span><br>        <span class="hljs-comment">//cal.set();</span><br>        cal.add(Calendar.DAY_OF_MONTH,<span class="hljs-number">5</span>);<br>        <span class="hljs-type">Date</span> <span class="hljs-variable">d</span> <span class="hljs-operator">=</span> cal.getTime();<br>        System.out.println(d);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="新增api">新增API</h6>
<figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs markdown">从Java8开始，java.time包提供了新的日期和时间APl,主要涉及的类型有：<br><br><span class="hljs-bullet">-</span> LocalDate:不包含具体时间的日期。<br><span class="hljs-bullet">-</span> LocalTime:不含日期的时间。<br><span class="hljs-bullet">-</span> LocalDateTime:包含了日期及时间。<br><span class="hljs-bullet">-</span> JDK8新增日期类<br><span class="hljs-bullet">-</span> Instant:代表的是时间戳。<br><span class="hljs-bullet">-</span> DateTimeFormatter用于做时间的格式化和解析的<br><span class="hljs-bullet">-</span> Duration:用于计算两个“时间”间隔<br><span class="hljs-bullet">-</span> Period:用于计算两个“日期”间隔<br><br>新增的AP叫严格区分了时刻、本地日期、本地时间，并且，对日期和时间进行运算更加方便。<br>其次，新API的类型几乎全部是不变类型(和String的使用类似)，可以放心使用不必担心被修改。<br></code></pre></td></tr></table></figure>
<p>代码：Day14。</p>
<h4 id="包装类">包装类</h4>
<p>包装类 其实就是8种基本数据类型对应的引用类型。</p>
<table>
<thead>
<tr class="header">
<th>基本数据类型</th>
<th>引用数据类型</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>byte</td>
<td>Byte</td>
</tr>
<tr class="even">
<td>short</td>
<td>Short</td>
</tr>
<tr class="odd">
<td>int</td>
<td>Integer</td>
</tr>
<tr class="even">
<td>long</td>
<td>Long</td>
</tr>
<tr class="odd">
<td>char</td>
<td>Character</td>
</tr>
<tr class="even">
<td>float</td>
<td>Float</td>
</tr>
<tr class="odd">
<td>double</td>
<td>Double</td>
</tr>
<tr class="even">
<td>boolean</td>
<td>Boolean</td>
</tr>
</tbody>
</table>
<p><strong>为什么提供包装类？</strong>
Java为了实现一切皆对象，为8种基本类型提供了对应的引用类型。
后面的集合和泛型其实也只能支持包装类型，不支持基本数据类型。</p>
<p>包装类的特有功能 包装类的变量的默认值可以是ul,容错率更高。
<strong>可以把基本类型的数据转换成字符串类型（用处不大）</strong>
①调用toString(）方法得到字符串结果。
②调用Integer.toString（）（基本类型的数据）。
<strong>可以把字符串类型的数值转换成真实的数据类型（真的很有用）</strong>
①Integer.parselnt(“字符串类型的整数”)。
②Double.parseDouble("字符串类型的小数”)。</p>
<p><strong>Integer.valueof() , Double.valueof()</strong></p>
<h4 id="正则表达式pattern">正则表达式Pattern</h4>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RegexDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">//public boolean matches(String regex):判断是否与正则表达式匹配，匹配返回true</span><br>        <span class="hljs-comment">// 只能是 a  b  c</span><br>        System.out.println(<span class="hljs-string">&quot;a&quot;</span>.matches(<span class="hljs-string">&quot;[abc]&quot;</span>)); <span class="hljs-comment">// true</span><br>        System.out.println(<span class="hljs-string">&quot;z&quot;</span>.matches(<span class="hljs-string">&quot;[abc]&quot;</span>)); <span class="hljs-comment">// false</span><br><br>        <span class="hljs-comment">// 不能出现a  b  c</span><br>        System.out.println(<span class="hljs-string">&quot;a&quot;</span>.matches(<span class="hljs-string">&quot;[^abc]&quot;</span>)); <span class="hljs-comment">// false</span><br>        System.out.println(<span class="hljs-string">&quot;z&quot;</span>.matches(<span class="hljs-string">&quot;[^abc]&quot;</span>)); <span class="hljs-comment">// true</span><br><br>        System.out.println(<span class="hljs-string">&quot;a&quot;</span>.matches(<span class="hljs-string">&quot;\\d&quot;</span>)); <span class="hljs-comment">// false</span><br>        System.out.println(<span class="hljs-string">&quot;3&quot;</span>.matches(<span class="hljs-string">&quot;\\d&quot;</span>)); <span class="hljs-comment">// true</span><br>        System.out.println(<span class="hljs-string">&quot;333&quot;</span>.matches(<span class="hljs-string">&quot;\\d&quot;</span>)); <span class="hljs-comment">// false</span><br>        System.out.println(<span class="hljs-string">&quot;z&quot;</span>.matches(<span class="hljs-string">&quot;\\w&quot;</span>)); <span class="hljs-comment">// true</span><br>        System.out.println(<span class="hljs-string">&quot;2&quot;</span>.matches(<span class="hljs-string">&quot;\\w&quot;</span>)); <span class="hljs-comment">// true</span><br>        System.out.println(<span class="hljs-string">&quot;21&quot;</span>.matches(<span class="hljs-string">&quot;\\w&quot;</span>)); <span class="hljs-comment">// false</span><br>        System.out.println(<span class="hljs-string">&quot;你&quot;</span>.matches(<span class="hljs-string">&quot;\\w&quot;</span>)); <span class="hljs-comment">//false</span><br>        System.out.println(<span class="hljs-string">&quot;你&quot;</span>.matches(<span class="hljs-string">&quot;\\W&quot;</span>)); <span class="hljs-comment">// true</span><br>        System.out.println(<span class="hljs-string">&quot;---------------------------------&quot;</span>);<br>        <span class="hljs-comment">//  以上正则匹配只能校验单个字符。</span><br><br>        <span class="hljs-comment">// 校验密码</span><br>        <span class="hljs-comment">// 必须是数字 字母 下划线 至少 6位</span><br>        System.out.println(<span class="hljs-string">&quot;2442fsfsf&quot;</span>.matches(<span class="hljs-string">&quot;\\w&#123;6,&#125;&quot;</span>));<br>        System.out.println(<span class="hljs-string">&quot;244f&quot;</span>.matches(<span class="hljs-string">&quot;\\w&#123;6,&#125;&quot;</span>));<br><br>        <span class="hljs-comment">// 验证码 必须是数字和字符  必须是4位</span><br>        System.out.println(<span class="hljs-string">&quot;23dF&quot;</span>.matches(<span class="hljs-string">&quot;[a-zA-Z0-9]&#123;4&#125;&quot;</span>));<br>        System.out.println(<span class="hljs-string">&quot;23_F&quot;</span>.matches(<span class="hljs-string">&quot;[a-zA-Z0-9]&#123;4&#125;&quot;</span>));<br>        System.out.println(<span class="hljs-string">&quot;23dF&quot;</span>.matches(<span class="hljs-string">&quot;[\\w&amp;&amp;[^_]]&#123;4&#125;&quot;</span>));<br>        System.out.println(<span class="hljs-string">&quot;23_F&quot;</span>.matches(<span class="hljs-string">&quot;[\\w&amp;&amp;[^_]]&#123;4&#125;&quot;</span>));<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>public boolean matches(<a
href="file:///D:/course/%E5%9F%BA%E7%A1%80%E9%98%B6%E6%AE%B5/API%E6%96%87%E6%A1%A3/docs/api/java.base/java/lang/String.html">String</a>
regex): 判断是否匹配正则表达式，匹配返回true，不匹配返回false。</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs css">字符类(默认匹配一个字符)<br><br><span class="hljs-selector-attr">[abc]</span>     只能是<span class="hljs-selector-tag">a</span>, <span class="hljs-selector-tag">b</span>, 或c<br><br><span class="hljs-selector-attr">[^abc]</span>     除了<span class="hljs-selector-tag">a</span>, <span class="hljs-selector-tag">b</span>, c之外的任何字符<br><br><span class="hljs-selector-attr">[a-zA-Z]</span>        <span class="hljs-selector-tag">a</span>到z <span class="hljs-selector-tag">A</span>到Z，包括（范围）<br><br><span class="hljs-selector-attr">[a-d[m-p]</span>]     <span class="hljs-selector-tag">a</span>到d，或m通过<span class="hljs-selector-tag">p</span>：（<span class="hljs-selector-attr">[a-dm-p]</span>联合）<br><br><span class="hljs-selector-attr">[a-z&amp;&amp;[def]</span>]     d, e, 或f(交集)<br><br><span class="hljs-selector-attr">[a-z&amp;&amp;[^bc]</span>]     <span class="hljs-selector-tag">a</span>到z，除了<span class="hljs-selector-tag">b</span>和c：（<span class="hljs-selector-attr">[ad-z]</span>减法）<br><br><span class="hljs-selector-attr">[a-z&amp;&amp;[^m-p]</span>]   <span class="hljs-selector-tag">a</span>到z，除了m到<span class="hljs-selector-tag">p</span>：（<span class="hljs-selector-attr">[a-lq-z]</span>减法）<br></code></pre></td></tr></table></figure>
<figure class="highlight livescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs livescript">预定义的字符类(默认匹配一个字符)<br>.	任何字符<br><span class="hljs-string">\d</span>	一个数字： [<span class="hljs-number">0</span>-<span class="hljs-number">9</span>]<br><span class="hljs-string">\D</span>	非数字： [^<span class="hljs-number">0</span>-<span class="hljs-number">9</span>]<br><span class="hljs-string">\s</span>	一个空白字符： [ <span class="hljs-string">\t\n\x0B\f\r]</span><br><span class="hljs-string">\S</span>	非空白字符： [^<span class="hljs-string">\s]</span><br><span class="hljs-string">\w</span>	[a-zA-Z_0-<span class="hljs-number">9</span>] 英文、数字、下划线<br><span class="hljs-string">\W</span>	 [^<span class="hljs-string">\w]</span> 一个非单词字符<br></code></pre></td></tr></table></figure>
<figure class="highlight tp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs tp">贪婪的量词（配合匹配多个字符）<br><span class="hljs-keyword">X</span>?	<span class="hljs-keyword">X</span> , 一次或根本不<br><span class="hljs-keyword">X</span>*	<span class="hljs-keyword">X</span>，零次或多次<br><span class="hljs-keyword">X</span>+	<span class="hljs-keyword">X</span> , 一次或多次<br><span class="hljs-keyword">X</span> &#123;n&#125;	<span class="hljs-keyword">X</span>，正好n次<br><span class="hljs-keyword">X</span> &#123;n, &#125;	<span class="hljs-keyword">X</span>，至少n次<br><span class="hljs-keyword">X</span> &#123;n,m&#125;	<span class="hljs-keyword">X</span>，至少n但不超过m次<br></code></pre></td></tr></table></figure>
<table>
<colgroup>
<col style="width: 46%" />
<col style="width: 53%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public String replaceAll(String regex,String newStr）</td>
<td>按照正则表达式匹配的内容进行替换</td>
</tr>
<tr class="even">
<td>public String[] split(String regex)：</td>
<td>按照正则表达式匹配的内容进行分割字符串，反回一个字符串数组。</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">package</span> com.itheima.d6_regex;<br><br><span class="hljs-keyword">import</span> java.util.regex.Matcher;<br><span class="hljs-keyword">import</span> java.util.regex.Pattern;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    拓展：正则表达式爬取信息中的内容。(了解)</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RegexDemo05</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;来黑马程序学习Java,电话020-43422424，或者联系邮箱&quot;</span> +<br>                <span class="hljs-string">&quot;itcast@itcast.cn,电话18762832633，0203232323&quot;</span> +<br>                <span class="hljs-string">&quot;邮箱bozai@itcast.cn，400-100-3233 ，4001003232&quot;</span>;<br><br>        <span class="hljs-comment">// 需求：从上面的内容中爬取出 电话号码和邮箱。</span><br>        <span class="hljs-comment">// 1、定义爬取规则，字符串形式</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">regex</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;(\\w&#123;1,30&#125;@[a-zA-Z0-9]&#123;2,20&#125;(\\.[a-zA-Z0-9]&#123;2,20&#125;)&#123;1,2&#125;)|(1[3-9]\\d&#123;9&#125;)&quot;</span> +<br>                <span class="hljs-string">&quot;|(0\\d&#123;2,6&#125;-?\\d&#123;5,20&#125;)|(400-?\\d&#123;3,9&#125;-?\\d&#123;3,9&#125;)&quot;</span>;<br><br>        <span class="hljs-comment">// 2、把这个爬取规则编译成匹配对象。</span><br>        <span class="hljs-type">Pattern</span> <span class="hljs-variable">pattern</span> <span class="hljs-operator">=</span> Pattern.compile(regex);<br><br>        <span class="hljs-comment">// 3、得到一个内容匹配器对象</span><br>        <span class="hljs-type">Matcher</span> <span class="hljs-variable">matcher</span> <span class="hljs-operator">=</span> pattern.matcher(rs);<br><br>        <span class="hljs-comment">// 4、开始找了</span><br>        <span class="hljs-keyword">while</span> (matcher.find()) &#123;<br>            <span class="hljs-type">String</span> <span class="hljs-variable">rs1</span> <span class="hljs-operator">=</span> matcher.group();<br>            System.out.println(rs1);<br>        &#125;<br><br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<h4 id="arrays类概述"><strong>Arrays</strong>类概述</h4>
<table>
<colgroup>
<col style="width: 55%" />
<col style="width: 44%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public static <a
href="mk:@MSITStore:C:\course\API文档\jdk-9_google.CHM::/java/lang/String.html">String</a>
toString(类型[] a)</td>
<td>返回数组的内容（字符串形式）</td>
</tr>
<tr class="even">
<td>public static void sort(类型[] a)</td>
<td>对数组进行默认升序排序</td>
</tr>
<tr class="odd">
<td>public static <T> void sort(类型[] a, <a
href="mk:@MSITStore:C:\course\API文档\jdk-9_google.CHM::/java/util/Comparator.html">Comparator</a>&lt;?
super T&gt; c)</td>
<td>使用比较器对象自定义排序</td>
</tr>
<tr class="even">
<td>public static int binarySearch(int[] a, int key)</td>
<td>二分搜索数组中的数据，存在返回索引，不存在返回-1</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">如果认为左边数据 大于 右边数据 返回正整数</span><br><span class="hljs-comment">如果认为左边数据 小于 右边数据  返回负整数</span><br><span class="hljs-comment">如果认为左边数据  等于 右边数据  返回0</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ArraysDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 目标：自定义数组的排序规则：Comparator比较器对象。</span><br>        <span class="hljs-comment">// 1、Arrays的sort方法对于有值特性的数组是默认升序排序</span><br>        <span class="hljs-type">int</span>[] ages = &#123;<span class="hljs-number">34</span>, <span class="hljs-number">12</span>, <span class="hljs-number">42</span>, <span class="hljs-number">23</span>&#125;;<br>        Arrays.sort(ages);<br>        System.out.println(Arrays.toString(ages));<br><br>        <span class="hljs-comment">// 2、需求：降序排序！(自定义比较器对象，只能支持引用类型的排序！！)</span><br>        Integer[] ages1 = &#123;<span class="hljs-number">34</span>, <span class="hljs-number">12</span>, <span class="hljs-number">42</span>, <span class="hljs-number">23</span>&#125;;<br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">           参数一：被排序的数组 必须是引用类型的元素</span><br><span class="hljs-comment">           参数二：匿名内部类对象，代表了一个比较器对象。</span><br><span class="hljs-comment">         */</span><br>        Arrays.sort(ages1, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Comparator</span>&lt;Integer&gt;() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">compare</span><span class="hljs-params">(Integer o1, Integer o2)</span> &#123;<br>                <span class="hljs-comment">// 指定比较规则。</span><br><span class="hljs-comment">//                if(o1 &gt; o2)&#123;</span><br><span class="hljs-comment">//                    return 1;</span><br><span class="hljs-comment">//                &#125;else if(o1 &lt; o2)&#123;</span><br><span class="hljs-comment">//                    return -1;</span><br><span class="hljs-comment">//                &#125;</span><br><span class="hljs-comment">//                return 0;</span><br>                <span class="hljs-comment">// return o1 - o2; // 默认升序</span><br>                <span class="hljs-keyword">return</span> o2 - o1; <span class="hljs-comment">//  降序</span><br>            &#125;<br>        &#125;);<br>        System.out.println(Arrays.toString(ages1));<br><br>        System.out.println(<span class="hljs-string">&quot;-------------------------&quot;</span>);<br>        Student[] students = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>[<span class="hljs-number">3</span>];<br>        students[<span class="hljs-number">0</span>] = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-string">&quot;吴磊&quot;</span>,<span class="hljs-number">23</span> , <span class="hljs-number">175.5</span>);<br>        students[<span class="hljs-number">1</span>] = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-string">&quot;谢鑫&quot;</span>,<span class="hljs-number">18</span> , <span class="hljs-number">185.5</span>);<br>        students[<span class="hljs-number">2</span>] = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-string">&quot;王亮&quot;</span>,<span class="hljs-number">20</span> , <span class="hljs-number">195.5</span>);<br>        System.out.println(Arrays.toString(students));<br><br>        <span class="hljs-comment">// Arrays.sort(students);  // 直接运行奔溃</span><br>        Arrays.sort(students, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Comparator</span>&lt;Student&gt;() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">compare</span><span class="hljs-params">(Student o1, Student o2)</span> &#123;<br>                <span class="hljs-comment">// 自己指定比较规则</span><br>                <span class="hljs-comment">// return o1.getAge() - o2.getAge(); // 按照年龄升序排序！</span><br>                <span class="hljs-comment">// return o2.getAge() - o1.getAge(); // 按照年龄降序排序！！</span><br>                <span class="hljs-comment">// return Double.compare(o1.getHeight(), o2.getHeight()); // 比较浮点型可以这样写 升序</span><br>                <span class="hljs-keyword">return</span> Double.compare(o2.getHeight(), o1.getHeight()); <span class="hljs-comment">// 比较浮点型可以这样写  降序</span><br>            &#125;<br>        &#125;);<br>        System.out.println(Arrays.toString(students));<br><br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="lambda表达式">Lambda表达式</h4>
<p><strong>Lambda概述</strong>
●Lambda:表达式是JDK8开始后的一种新语法形式。
●作用：简化匿名内部类的代码写法。
<strong>Lambda表达式的简化格式</strong></p>
<figure class="highlight clean"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs clean">（匿名内部类被重写方法的形参列表）-&gt;&#123;<br>被重写方法的方法体代码。<br>&#125;<br>注：-&gt;是语法形式，无实际含义<br></code></pre></td></tr></table></figure>
<p><strong>注意：Lambda表达式只能简化函数式接口的匿名内部类的写法形式</strong></p>
<p>什么是函数式接口？
●首先必须是接口、其次接口中有且仅有一个抽象方法的形式
●通常我们会在接口上加上一个@Functionallnterface注解，标记该接口必须是满足函数式接口。</p>
<p>1、Lambda表达式的基本作用？ ●简化函数式接口的匿名内部类的写法。
2、Lambda表达式有什么使用前提？
●必须是接口的匿名内部类，接口中只能有一个抽象方法 3、Lambda的好处？
●Lambda是一个匿名函数，我们可以把Lambda表达式理解为
是一段可以传递的代码，它可以写出更简洁、更灵活的代码，
作为一种更紧凑的代码风格，使va语言表达能力得到了提升。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">LambdaDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 目标：学会使用Lambda的标准格式简化匿名内部类的代码形式</span><br>        <span class="hljs-comment">// 注意：Lambda只能简化接口中只有一个抽象方法的匿名内部类形式（函数式接口）</span><br><span class="hljs-comment">//        Swimming s1 = new Swimming() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public void swim() &#123;</span><br><span class="hljs-comment">//                System.out.println(&quot;老师游泳贼溜~~~~~&quot;);</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;;</span><br><br><span class="hljs-comment">//        Swimming s1 = () -&gt; &#123;</span><br><span class="hljs-comment">//            System.out.println(&quot;老师游泳贼溜~~~~~&quot;);</span><br><span class="hljs-comment">//        &#125;;</span><br><br>        <span class="hljs-type">Swimming</span> <span class="hljs-variable">s1</span> <span class="hljs-operator">=</span> () -&gt; System.out.println(<span class="hljs-string">&quot;老师游泳贼溜~~~~~&quot;</span>);<br>        go(s1);<br><br>        System.out.println(<span class="hljs-string">&quot;---------------------&quot;</span>);<br><span class="hljs-comment">//        go(new Swimming() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public void swim() &#123;</span><br><span class="hljs-comment">//                System.out.println(&quot;学生游泳很开心~~~&quot;);</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;);</span><br><br><span class="hljs-comment">//        go(() -&gt;&#123;</span><br><span class="hljs-comment">//                System.out.println(&quot;学生游泳很开心~~~&quot;);</span><br><span class="hljs-comment">//        &#125;);</span><br><br>        go(() -&gt; System.out.println(<span class="hljs-string">&quot;学生游泳很开心~~~&quot;</span>));<br><br><br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">go</span><span class="hljs-params">(Swimming s)</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;开始。。。&quot;</span>);<br>        s.swim();<br>        System.out.println(<span class="hljs-string">&quot;结束。。。&quot;</span>);<br>    &#125;<br>&#125;<br><br><span class="hljs-meta">@FunctionalInterface</span> <span class="hljs-comment">// 一旦加上这个注解必须是函数式接口，里面只能有一个抽象方法</span><br><span class="hljs-keyword">interface</span> <span class="hljs-title class_">Swimming</span>&#123;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">swim</span><span class="hljs-params">()</span>;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs kotlin">Lambda表达式的省略写法(进一步在Lambda表达式的基础上继续简化)<br>参数类型可以省略不写。<br>●如果只有一个参数，参数类型可以省略，同时）也可以省略。<br>●如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写，同时要省略分号！<br>●如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写。此时，如果这行代码是<span class="hljs-keyword">return</span>语句，必须省略<span class="hljs-keyword">return</span>不写，同时也必须省略<span class="hljs-string">&quot;，&quot;</span>不写<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">LambdaDemo3</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        Integer[] ages1 = &#123;<span class="hljs-number">34</span>, <span class="hljs-number">12</span>, <span class="hljs-number">42</span>, <span class="hljs-number">23</span>&#125;;<br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">         参数一：被排序的数组 必须是引用类型的元素</span><br><span class="hljs-comment">         参数二：匿名内部类对象，代表了一个比较器对象。</span><br><span class="hljs-comment">         */</span><br><span class="hljs-comment">//        Arrays.sort(ages1, new Comparator&lt;Integer&gt;() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public int compare(Integer o1, Integer o2) &#123;</span><br><span class="hljs-comment">//                return o2 - o1; //  降序</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;);</span><br><br><span class="hljs-comment">//        Arrays.sort(ages1, (Integer o1, Integer o2) -&gt; &#123;</span><br><span class="hljs-comment">//                return o2 - o1; //  降序</span><br><span class="hljs-comment">//        &#125;);</span><br><br><br><span class="hljs-comment">//        Arrays.sort(ages1, ( o1,  o2) -&gt; &#123;</span><br><span class="hljs-comment">//            return o2 - o1; //  降序</span><br><span class="hljs-comment">//        &#125;);</span><br><br>        Arrays.sort(ages1, ( o1,  o2 ) -&gt;  o2 - o1 );<br><br>        System.out.println(Arrays.toString(ages1));<br><br>        System.out.println(<span class="hljs-string">&quot;---------------------------&quot;</span>);<br>        <span class="hljs-type">JFrame</span> <span class="hljs-variable">win</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">JFrame</span>(<span class="hljs-string">&quot;登录界面&quot;</span>);<br>        <span class="hljs-type">JButton</span> <span class="hljs-variable">btn</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">JButton</span>(<span class="hljs-string">&quot;我是一个很大的按钮&quot;</span>);<br><span class="hljs-comment">//        btn.addActionListener(new ActionListener() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public void actionPerformed(ActionEvent e) &#123;</span><br><span class="hljs-comment">//                System.out.println(&quot;有人点我，点我，点我！！&quot;);</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;);</span><br><br><span class="hljs-comment">//        btn.addActionListener((ActionEvent e) -&gt; &#123;</span><br><span class="hljs-comment">//                System.out.println(&quot;有人点我，点我，点我！！&quot;);</span><br><span class="hljs-comment">//        &#125;);</span><br><br><span class="hljs-comment">//        btn.addActionListener(( e) -&gt; &#123;</span><br><span class="hljs-comment">//            System.out.println(&quot;有人点我，点我，点我！！&quot;);</span><br><span class="hljs-comment">//        &#125;);</span><br><br><span class="hljs-comment">//        btn.addActionListener( e -&gt; &#123;</span><br><span class="hljs-comment">//            System.out.println(&quot;有人点我，点我，点我！！&quot;);</span><br><span class="hljs-comment">//        &#125;);</span><br><br>        btn.addActionListener( e -&gt; System.out.println(<span class="hljs-string">&quot;有人点我，点我，点我！！&quot;</span>) );<br>        <br>        win.add(btn);<br>        win.setSize(<span class="hljs-number">400</span>, <span class="hljs-number">300</span>);<br>        win.setVisible(<span class="hljs-literal">true</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="集合collection">集合collection</h4>
<p>集合是java中存储对象数据的一种容器。</p>
<h6 id="集合的特点"><strong>集合的特点</strong></h6>
<ul>
<li>集合的大小不固定，启动后可以动态变化，类型也可以选择不固定。集合更像气球。</li>
<li>集合非常适合做元素的增删操作。</li>
<li>注意：集合中只能存储<strong>引用类型数据</strong>，如果要存储基本类型数据可以选用包装类。</li>
</ul>
<p><strong>1、数组和集合的元素存储的个数问题。</strong>
●数组定义后类型确定，长度固定 ●集合类型可以不固定，大小是可变的。
<strong>2、数组和集合存储元素的类型问题。</strong>
●数组可以存储基本类型和引用类型的数据。
●集合只能存储引用数据类型的数据。
<strong>3、数组和集合适合的场景</strong>
●数组适合做数据个数和类型确定的场景。
●集合适合做数据个数不确定，且要做增删元素的场景。</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220425105730336.png" srcset="/img/loading.gif" lazyload class="">
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220425105950636.png" srcset="/img/loading.gif" lazyload class="">
<p><strong>Collection集合特点</strong>
●<strong>List系列集合</strong>：添加的元素是有序、可重复、有索引。
◆ArrayList、LinekdList:有序。可重复、有奏引。
●<strong>Set系列集合</strong>：添加的元素是无序、不重复、无索引。
◆HashSet:无序、不重复、无索引；LinkedHashSet:<strong>有序</strong>、不重复、无索引。
◆TreeSet:<strong>按照大小默认升序排序</strong>、不重复、无索引。</p>
<h6 id="集合常用用法及常用api">集合常用用法及常用API</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java">Collection &lt;String&gt; = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>Collection &lt;Integer&gt; = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>Collection &lt;Double&gt; = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>Object[] arrs =c.toArrays()<span class="hljs-comment">//把集合转化为整数</span><br></code></pre></td></tr></table></figure>
<table>
<colgroup>
<col style="width: 52%" />
<col style="width: 47%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public boolean add(E e)</td>
<td>把给定的对象添加到当前集合中</td>
</tr>
<tr class="even">
<td>public void clear()</td>
<td>清空集合中所有的元素</td>
</tr>
<tr class="odd">
<td>public boolean remove(E e)</td>
<td>把给定的对象在当前集合中删除</td>
</tr>
<tr class="even">
<td>public boolean contains(Object obj)</td>
<td>判断当前集合中是否包含给定的对象</td>
</tr>
<tr class="odd">
<td>public boolean isEmpty()</td>
<td>判断当前集合是否为空</td>
</tr>
<tr class="even">
<td>public int size()</td>
<td>返回集合中元素的个数。</td>
</tr>
<tr class="odd">
<td>public Object[] toArray()</td>
<td>把集合中的元素，存储到数组中</td>
</tr>
</tbody>
</table>
<p><strong>遍历集合</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java">Iterator&lt;String&gt; it = lists.iterator();<br> <span class="hljs-keyword">while</span>(it.hasNext())&#123;<br>   <span class="hljs-type">String</span> <span class="hljs-variable">ele</span> <span class="hljs-operator">=</span> it.next();<br>   System.out.println(ele);<br> &#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java">Collection&lt;String&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br><span class="hljs-keyword">for</span>(String ele : list) &#123;<span class="hljs-comment">//list.for快捷键</span><br>	System.out.println(ele);<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java">lists.forEach(s -&gt; &#123;<br>      System.out.println(s);<br> &#125;);<br></code></pre></td></tr></table></figure>
<h6
id="各种数据结构的特点和作用是什么样的">各种数据结构的特点和作用是什么样的</h6>
<ul>
<li>队列：先进先出，后进后出。</li>
<li>栈：后进先出，先进后出。</li>
<li>数组：内存连续区域，查询快，增删慢。</li>
<li>链表：元素是游离的，查询慢，首尾操作极快。</li>
<li>二叉树：永远只有一个根节点，每个结点不超过2个子节点的树。</li>
<li>查找二叉树：小的左边，大的右边，但是可能树很高，查询性能变差。</li>
<li>平衡查找二叉树：让树的高度差不大于1，增删改查都提高了。</li>
<li>红黑树（就是基于红黑规则实现了自平衡的排序二叉树）</li>
</ul>
<h6 id="arraylist集合底层原理">ArrayList集合底层原理</h6>
<p>ArrayList底层是基于数组实现的：根据索引定位元素快，增删需要做元素的移位操作。
第一次创建集合并添加第一个元素的时候，在底层创建一个默认长度为10的数组。满了后每次扩容1.5倍，迁移。</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220425201738284.png" srcset="/img/loading.gif" lazyload class="">
<h6
id="linkedlist的特点适用于栈和队列">LinkedList的特点(适用于栈和队列)</h6>
<p>●底层数据结构是双链表，查询慢，首尾操作的速度是极快的，所以多了很多首尾操作的特有API。</p>
<table>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void addFirst(E e)</td>
<td>在该列表开头插入指定的元素</td>
</tr>
<tr class="even">
<td>public void addLast(E e)</td>
<td>将指定的元素追加到此列表的末尾</td>
</tr>
<tr class="odd">
<td>public E getFirst()</td>
<td>返回此列表中的第一个元素</td>
</tr>
<tr class="even">
<td>public E getLast()</td>
<td>返回此列表中的最后一个元素</td>
</tr>
<tr class="odd">
<td>public E removeFirst()</td>
<td>从此列表中删除并返回第一个元素</td>
</tr>
<tr class="even">
<td>public E removeLast()</td>
<td>从此列表中删除并返回最后一个元素</td>
</tr>
</tbody>
</table>
<h6 id="并发增删异常">并发增删异常</h6>
<p><strong>当我们从集合中找出某个元素并删除的时候可能出现一种并发修改异常问题。</strong>
<strong>哪些遍历存在问题？</strong>
迭代器遍历集合且直接用集合删除元素的时候可能出现。</p>
<p>增强for循环遍历集合且直接用集合删除元素的时候可能出现。</p>
<p><strong>哪种遍历且删除元素不出问题</strong>
迭代器遍历集合但是用迭代器自己的删除方法操作可以解决。</p>
<p>使用for循环遍历并别除元素不会存在这个问题。</p>
<h4 id="泛型概述">泛型概述</h4>
<ul>
<li>泛型：是DK5中引入的特性，可以在编译阶段约束操作的数据类型，并进行检查。</li>
<li>泛型的格式：<数据类型>；注意：泛型只能支持引用数据类型。</li>
<li>集合体系的全部接口和实现类都是支持泛型的使用的。</li>
</ul>
<h6 id="泛型的好处">泛型的好处：</h6>
<ul>
<li>统一数据类型。</li>
<li>把运行时期的问题提前到了编译期间，避免了强制类型转换可能出现的异常，因为编译阶段类型就能确定下来。</li>
</ul>
<p><strong>模拟ArrayList集合自定义一个集合MyArrayLists集合，完成添加和删除功能的泛型设计即可。</strong></p>
<h6 id="泛型类的核心思想"><strong>1、泛型类的核心思想：</strong></h6>
<p>把出现泛型变量的地方全部替换成传输的真实数据类型</p>
<h6 id="泛型类的作用"><strong>2、泛型类的作用</strong></h6>
<p>编译阶段约定操作的数据的类型，类似于集合的作用。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>    <span class="hljs-comment">// 需求：模拟ArrayList定义一个MyArrayList ，关注泛型设计</span><br>    MyArrayList&lt;String&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyArrayList</span>&lt;&gt;();<br>    list.add(<span class="hljs-string">&quot;Java&quot;</span>);<br>    list.add(<span class="hljs-string">&quot;Java&quot;</span>);<br>    list.add(<span class="hljs-string">&quot;MySQL&quot;</span>);<br>    list.remove(<span class="hljs-string">&quot;MySQL&quot;</span>);<br>    System.out.println(list);<br><br>    MyArrayList&lt;Integer&gt; list2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyArrayList</span>&lt;&gt;();<br>    list2.add(<span class="hljs-number">23</span>);<br>    list2.add(<span class="hljs-number">24</span>);<br>    list2.add(<span class="hljs-number">25</span>);<br>    list2.remove(<span class="hljs-number">25</span>);<br>    System.out.println(list2);<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyArrayList</span>&lt;E&gt; &#123;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">ArrayList</span> <span class="hljs-variable">lists</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>();<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(E e)</span>&#123;<br>        lists.add(e);<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">remove</span><span class="hljs-params">(E e)</span>&#123;<br>        lists.remove(e);<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">toString</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> lists.toString();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="泛型方法的概述">泛型方法的概述</h6>
<p>定义方法时同时定义了泛型的方法就是泛型方法。
泛型方法的格式：修饰符<泛型变量>方法返回值方法名称（形参列表）川</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java">范例：<span class="hljs-keyword">public</span>&lt;T&gt;<span class="hljs-keyword">void</span> <span class="hljs-title function_">show</span><span class="hljs-params">(T t)</span>&#123;&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">GenericDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        String[] names = &#123;<span class="hljs-string">&quot;小璐&quot;</span>, <span class="hljs-string">&quot;蓉容&quot;</span>, <span class="hljs-string">&quot;小何&quot;</span>&#125;;<br>        printArray(names);<br><br>        Integer[] ages = &#123;<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>&#125;;<br>        printArray(ages);<br><br>        Integer[] ages2 = getArr(ages);<br>        String[]  names2 = getArr(names);<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; T[] getArr(T[] arr)&#123;<br>        <span class="hljs-keyword">return</span> arr;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; <span class="hljs-keyword">void</span> <span class="hljs-title function_">printArray</span><span class="hljs-params">(T[] arr)</span>&#123;<br>        <span class="hljs-keyword">if</span>(arr != <span class="hljs-literal">null</span>)&#123;<br>            <span class="hljs-type">StringBuilder</span> <span class="hljs-variable">sb</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>(<span class="hljs-string">&quot;[&quot;</span>);<br>            <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; arr.length; i++) &#123;<br>                sb.append(arr[i]).append(i == arr.length - <span class="hljs-number">1</span> ? <span class="hljs-string">&quot;&quot;</span> : <span class="hljs-string">&quot;, &quot;</span>);<br>            &#125;<br>            sb.append(<span class="hljs-string">&quot;]&quot;</span>);<br>            System.out.println(sb);<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            System.out.println(arr);<br>        &#125;<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<h6 id="泛型接口的概述">泛型接口的概述</h6>
<p>使用了泛型定义的接口就是泛型接口。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java">泛型接口的格式：修饰符interface接口名称&lt;泛型变量&gt;&#123;&#125;<br>范例：<span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">Data</span>&lt;E&gt;&#123;&#125;<br></code></pre></td></tr></table></figure>
<p>作用：泛型接口可以让实现类选择当前功能需要操作的数据类型。</p>
<p>教务系统，提供一个接口可约束一定要完成数据（学生，老师）的增删改查操作</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">Data</span>&lt;E&gt; &#123;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(E e)</span>;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">delete</span><span class="hljs-params">(<span class="hljs-type">int</span> id)</span>;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">update</span><span class="hljs-params">(E e)</span>;<br>    E <span class="hljs-title function_">queryById</span><span class="hljs-params">(<span class="hljs-type">int</span> id)</span>;<br>&#125;<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TeacherData</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Data</span>&lt;Teacher&gt;&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">add</span><span class="hljs-params">(Teacher teacher)</span> &#123;<br><br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">delete</span><span class="hljs-params">(<span class="hljs-type">int</span> id)</span> &#123;<br><br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">update</span><span class="hljs-params">(Teacher teacher)</span> &#123;<br><br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> Teacher <span class="hljs-title function_">queryById</span><span class="hljs-params">(<span class="hljs-type">int</span> id)</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：泛型通配符。?</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    需求：开发一个极品飞车的游戏，所有的汽车都能一起参与比赛。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    注意：</span><br><span class="hljs-comment">        虽然BMW和BENZ都继承了Car</span><br><span class="hljs-comment">        但是ArrayList&lt;BMW&gt;和ArrayList&lt;BENZ&gt;与ArrayList&lt;Car&gt;没有关系的！!</span><br><span class="hljs-comment">    通配符：？</span><br><span class="hljs-comment">        ？可以在“使用泛型”的时候代表一切类型。</span><br><span class="hljs-comment">        E T K V 是在定义泛型的时候使用的。</span><br><span class="hljs-comment">    泛型的上下限：</span><br><span class="hljs-comment">        ？ extends Car : ?必须是Car或者其子类  泛型上限</span><br><span class="hljs-comment">        ? super Car ：？必须是Car或者其父类   泛型下限</span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">        通配符：？</span><br><span class="hljs-comment">        ？可以在“使用泛型”的时候代表一切类型。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">GenericDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        ArrayList&lt;BMW&gt; bmws = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        bmws.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">BMW</span>());<br>        bmws.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">BMW</span>());<br>        bmws.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">BMW</span>());<br>        go(bmws);<br><br>        ArrayList&lt;BENZ&gt; benzs = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        benzs.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">BENZ</span>());<br>        benzs.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">BENZ</span>());<br>        benzs.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">BENZ</span>());<br>        go(benzs);<br><br>        ArrayList&lt;Dog&gt; dogs = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        dogs.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Dog</span>());<br>        dogs.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Dog</span>());<br>        dogs.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Dog</span>());<br>        <span class="hljs-comment">// go(dogs);</span><br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       所有车比赛，?通配符</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">go</span><span class="hljs-params">(ArrayList&lt;? extends Car&gt; cars)</span>&#123;<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Dog</span>&#123;<br><br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BENZ</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Car</span>&#123;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BMW</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Car</span>&#123;<br>&#125;<br><br><span class="hljs-comment">// 父类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Car</span>&#123;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="set集合"><strong>Set集合</strong></h4>
<h6 id="set系列集合特点">Set系列集合特点</h6>
<p><strong>无序</strong>：存取顺序不一致
<strong>不重复</strong>：可以去除重复
<strong>无索引</strong>：没有带索引的方法，所以不能使用普通fo循环遍历，也不能通过索引来获取元素。</p>
<h6 id="set集合实现类特点">Set集合实现类特点</h6>
<p><strong>HashSet</strong>:无序、不重复、无索引。
<strong>LinkedHashSet</strong>:有序、不重复、无索引。
<strong>TreeSet</strong>:排序、不重复、无索引。</p>
<h6 id="hashset底层原理">HashSet底层原理</h6>
<ul>
<li>HashSets集合底层采取哈希表存储的数据。</li>
<li>哈希表是一种对于增删改查数据性能都较好的结构。</li>
</ul>
<h6 id="哈希值">哈希值</h6>
<ul>
<li>是JDK根据对象的地址，按照某种规则算出来的it类型的数值。</li>
<li>Object类的API:public int hashCode（）:返回对象的哈希值</li>
</ul>
<h6 id="对象的哈希值特点">对象的哈希值特点</h6>
<ul>
<li>同一个对象多次调用nashCode(O方法返回的哈希值是相同的</li>
<li>默认情况下，不同对象的哈希值是不同的。</li>
</ul>
<p><img src="JAVA基础/image-20220426143136185.png" srcset="/img/loading.gif" lazyload alt="image-20220426143136185" style="zoom:50%;" /></p>
<ol type="1">
<li><p>创建一个默认长度16的数组，数组名table</p></li>
<li><p>根据元素的哈希值跟数组的长度求余计算出应存入的位置（哈希算法）</p></li>
<li><p>判断当前位置是否为null,如果是null直接存入</p></li>
<li><p>如果位置不为null,表示有元素，则调用equals方法比较</p></li>
<li><p>如果一样，则不存，如果不一样，则存入数组，</p>
<ul>
<li><p>​ DK7新元素占老元素位置，指向老元素</p></li>
<li><p>​ JDK8中新元素挂在老元素下面</p></li>
</ul></li>
</ol>
<h6
id="jdk1.8版本开始hashset原理解析">JDK1.8版本开始HashSet原理解析</h6>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220426143547400.png" srcset="/img/loading.gif" lazyload class="">
<p>1.底层结构：哈希表(数组、链表、红黑树的结合体)。
2.当挂在元素下面的数据过多时，查询性能降低，从JDK8开始后，当链表长度超过8的时候，自动转换为红黑树。</p>
<h6 id="哈希表的详细流程">2.哈希表的详细流程</h6>
<p>①创建一个默认长度16，默认加载因为0.75的数组，数组名table。
②根据元素的哈希值跟数组的长度计算出应存入的位置。
③判断当前位置是否为nul,如果是nul直接存入，如果位置不为null,表示有元素则调用equals方法比较属性值，如果一样，则不存，如果不一样，则存入数组。
④当数组存满到16*0.75=12时，就自动扩容，每次扩容原先的两倍</p>
<p>结论：如果希望Set集合认为2个内容一样的对象是重复的，必须重写对象的hashCode()和equals()方法</p>
<h6 id="linkhashset原理">linkhashset原理：</h6>
<p>原理：底层数据结构是依然哈希表，只是每个元素又额外的多了一个双链表的机制记录存储的顺序。</p>
<h6 id="treeset集合概述和特点">TreeSet集合概述和特点</h6>
<p>不重复、无索引、可排序
可排序：按照元素的大小默认升序（有小到大）排序。
TreeSet集合底层是基于红黑树的数据结构实现排序的，增删改查性能好。
注意：TreeSet集合是一定要排序的，可以将元素按照指定的规则进行序。</p>
<p>2.TreeSet集合自定义排序规则有几种方式 ●2种。
●类实现Comparable接口，重写比较规则。
●集合自定义Comparator比较器对象，重写比较规则。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Apple</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Comparable</span>&lt;Apple&gt;&#123;<br>    <span class="hljs-keyword">private</span> String name;<br>    <span class="hljs-keyword">private</span> String color;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">double</span> price;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> weight;<br>    .<br>    .<br>    .<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">      方式一：类自定义比较规则</span><br><span class="hljs-comment">      o1.compareTo(o2)</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> o</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">compareTo</span><span class="hljs-params">(Apple o)</span> &#123;<br>        <span class="hljs-comment">// 按照重量进行比较的</span><br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.weight - o.weight ; <span class="hljs-comment">// 去重重量重复的元素</span><br>        <span class="hljs-comment">// return this.weight - o.weight &gt;= 0 ? 1 : -1; // 保留重量重复的元素</span><br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">SetDemo5</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        Set&lt;Integer&gt; sets = <span class="hljs-keyword">new</span> <span class="hljs-title class_">TreeSet</span>&lt;&gt;(); <span class="hljs-comment">// 不重复 无索引 可排序</span><br>        sets.add(<span class="hljs-number">23</span>);<br>        sets.add(<span class="hljs-number">24</span>);<br>        sets.add(<span class="hljs-number">12</span>);<br>        sets.add(<span class="hljs-number">8</span>);<br>        System.out.println(sets);<br><br>        Set&lt;String&gt; sets1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">TreeSet</span>&lt;&gt;(); <span class="hljs-comment">// 不重复 无索引 可排序</span><br>        sets1.add(<span class="hljs-string">&quot;Java&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;Java&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;angela&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;黑马&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;Java&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;About&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;Python&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;UI&quot;</span>);<br>        sets1.add(<span class="hljs-string">&quot;UI&quot;</span>);<br>        System.out.println(sets1);<br><br>        System.out.println(<span class="hljs-string">&quot;------------------------------&quot;</span>);<br>        <span class="hljs-comment">// 方式二：集合自带比较器对象进行规则定制</span><br>        <span class="hljs-comment">//</span><br><span class="hljs-comment">//        Set&lt;Apple&gt; apples = new TreeSet&lt;&gt;(new Comparator&lt;Apple&gt;() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public int compare(Apple o1, Apple o2) &#123;</span><br><span class="hljs-comment">//                // return o1.getWeight() - o2.getWeight(); // 升序</span><br><span class="hljs-comment">//                // return o2.getWeight() - o1.getWeight(); // 降序</span><br><span class="hljs-comment">//                // 注意：浮点型建议直接使用Double.compare进行比较</span><br><span class="hljs-comment">//                // return Double.compare(o1.getPrice() , o2.getPrice()); // 升序</span><br><span class="hljs-comment">//                return Double.compare(o2.getPrice() , o1.getPrice()); // 降序</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;);</span><br><br>        Set&lt;Apple&gt; apples = <span class="hljs-keyword">new</span> <span class="hljs-title class_">TreeSet</span>&lt;&gt;(( o1,  o2) -&gt;  Double.compare(o2.getPrice() , o1.getPrice())  );<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;红富士&quot;</span>, <span class="hljs-string">&quot;红色&quot;</span>, <span class="hljs-number">9.9</span>, <span class="hljs-number">500</span>));<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;青苹果&quot;</span>, <span class="hljs-string">&quot;绿色&quot;</span>, <span class="hljs-number">15.9</span>, <span class="hljs-number">300</span>));<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;绿苹果&quot;</span>, <span class="hljs-string">&quot;青色&quot;</span>, <span class="hljs-number">29.9</span>, <span class="hljs-number">400</span>));<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;黄苹果&quot;</span>, <span class="hljs-string">&quot;黄色&quot;</span>, <span class="hljs-number">9.8</span>, <span class="hljs-number">500</span>));<br>        System.out.println(apples);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="总结">总结</h6>
<p>1.如果希望元素可以重复，又有索引，索引查询要快？
●用ArrayList?集合，基于数组的。（用的最多）
2.如果希望元素可以重复，又有索引，增删首尾操作快？
●用LinkedList集合，基于链表的。
3.如果希望增删改查都快，但是元素不重复、无序、无索引。
●用HashSet集合，基于哈希表的。
4.如果希望增删改查都快，但是元素不重复、有序、无索引。
●用LinkedHashSet集合，基于哈希表和双链表。 5.如果要对对象进行排序。
●用TreeSet:集合，基于红黑树。后续也可以用List集合实现排序。</p>
<h6 id="可变参数">可变参数</h6>
<p>●可变参数用在形参中可以接收多个数据。
可变参数的格式：数据类型…参数名称 <strong>可变参数的作用</strong>
●传输参数非常灵活，方便。可以不传输参数，可以传输1个或者多个，也可以传输一个数组</p>
<p>●可变参数在方法内部本质上就是一个数组。</p>
<p><strong>可变参数的注意事项：</strong>
●1.一个形参列表中可变参数只能有一个
●2.可变参数必须放在形参列表的最后面</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MethodDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br><br>        sum(); <span class="hljs-comment">// 1、不传参数</span><br>        sum(<span class="hljs-number">10</span>); <span class="hljs-comment">// 2、可以传输一个参数</span><br>        sum(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>); <span class="hljs-comment">// 3、可以传输多个参数</span><br>        sum(<span class="hljs-keyword">new</span> <span class="hljs-title class_">int</span>[]&#123;<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-number">30</span>, <span class="hljs-number">40</span>, <span class="hljs-number">50</span>&#125;); <span class="hljs-comment">// 4、可以传输一个数组</span><br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       注意：一个形参列表中只能有一个可变参数,可变参数必须放在形参列表的最后面</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> nums</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">sum</span><span class="hljs-params">(  <span class="hljs-type">int</span>...nums)</span>&#123;<br>        <span class="hljs-comment">// 注意：可变参数在方法内部其实就是一个数组。 nums</span><br>        System.out.println(<span class="hljs-string">&quot;元素个数：&quot;</span> + nums.length);<br>        System.out.println(<span class="hljs-string">&quot;元素内容：&quot;</span> + Arrays.toString(nums));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="collections">Collections</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Collections工具类的使用。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    java.utils.Collections:是集合工具类</span><br><span class="hljs-comment">    Collections并不属于集合，是用来操作集合的工具类。</span><br><span class="hljs-comment">    Collections有几个常用的API:</span><br><span class="hljs-comment">         - public static &lt;T&gt; boolean addAll(Collection&lt;? super T&gt; c, T... elements)</span><br><span class="hljs-comment">             给集合对象批量添加元素！</span><br><span class="hljs-comment">         - public static void shuffle(List&lt;?&gt; list) :打乱集合顺序。</span><br><span class="hljs-comment">         - public static &lt;T&gt; void sort(List&lt;T&gt; list):将集合中元素按照默认规则排序。</span><br><span class="hljs-comment">         - public static &lt;T&gt; void sort(List&lt;T&gt; list，Comparator&lt;? super T&gt; c):将集合中元素按照指定规则排序。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CollectionsDemo01</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        List&lt;String&gt; names = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        <span class="hljs-comment">//names.add(&quot;楚留香&quot;);</span><br>        <span class="hljs-comment">//names.add(&quot;胡铁花&quot;);</span><br>        <span class="hljs-comment">//names.add(&quot;张无忌&quot;);</span><br>        <span class="hljs-comment">//names.add(&quot;陆小凤&quot;);</span><br>        Collections.addAll(names, <span class="hljs-string">&quot;楚留香&quot;</span>,<span class="hljs-string">&quot;胡铁花&quot;</span>, <span class="hljs-string">&quot;张无忌&quot;</span>,<span class="hljs-string">&quot;陆小凤&quot;</span>);<br>        System.out.println(names);<br><br>        <span class="hljs-comment">// 2、public static void shuffle(List&lt;?&gt; list) :打乱集合顺序。</span><br>        Collections.shuffle(names);<br>        System.out.println(names);<br><br>        <span class="hljs-comment">// 3、 public static &lt;T&gt; void sort(List&lt;T&gt; list):将集合中元素按照默认规则排序。 （排值特性的元素）</span><br>        List&lt;Integer&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        Collections.addAll(list, <span class="hljs-number">12</span>, <span class="hljs-number">23</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>);<br>        System.out.println(list);<br>        Collections.sort(list);<br>        System.out.println(list);<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：引用数据类型的排序。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    字符串按照首字符的编号升序排序！</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    自定义类型的比较方法API:Collections</span><br><span class="hljs-comment">         - public static &lt;T&gt; void sort(List&lt;T&gt; list):</span><br><span class="hljs-comment">               将集合中元素按照默认规则排序。</span><br><span class="hljs-comment">               对于自定义的引用类型的排序人家根本不知道怎么排，直接报错！</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">         - public static &lt;T&gt; void sort(List&lt;T&gt; list，Comparator&lt;? super T&gt; c):</span><br><span class="hljs-comment">                将集合中元素按照指定规则排序,自带比较器</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CollectionsDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        List&lt;Apple&gt; apples = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;(); <span class="hljs-comment">// 可以重复！</span><br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;红富士&quot;</span>, <span class="hljs-string">&quot;红色&quot;</span>, <span class="hljs-number">9.9</span>, <span class="hljs-number">500</span>));<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;青苹果&quot;</span>, <span class="hljs-string">&quot;绿色&quot;</span>, <span class="hljs-number">15.9</span>, <span class="hljs-number">300</span>));<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;绿苹果&quot;</span>, <span class="hljs-string">&quot;青色&quot;</span>, <span class="hljs-number">29.9</span>, <span class="hljs-number">400</span>));<br>        apples.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Apple</span>(<span class="hljs-string">&quot;黄苹果&quot;</span>, <span class="hljs-string">&quot;黄色&quot;</span>, <span class="hljs-number">9.8</span>, <span class="hljs-number">500</span>));<br><br><span class="hljs-comment">//        Collections.sort(apples); // 方法一：可以的，Apple类已经重写了比较规则</span><br><span class="hljs-comment">//        System.out.println(apples);</span><br><br>        <span class="hljs-comment">// 方式二：sort方法自带比较器对象</span><br><span class="hljs-comment">//        Collections.sort(apples, new Comparator&lt;Apple&gt;() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public int compare(Apple o1, Apple o2) &#123;</span><br><span class="hljs-comment">//                return Double.compare(o1.getPrice() , o2.getPrice()); // 按照价格排序！！</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;);</span><br><br>        Collections.sort(apples, ( o1,  o2) -&gt;  Double.compare(o1.getPrice() , o2.getPrice()) );<br>        System.out.println(apples);<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="斗地主发牌案例">斗地主发牌案例：</h6>
<p>能把Collection和Collections串起来</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Card</span> &#123;<br>    <span class="hljs-keyword">private</span> String size;<br>    <span class="hljs-keyword">private</span> String color;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> index; <span class="hljs-comment">// 牌的真正大小</span><br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Card</span><span class="hljs-params">()</span>&#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Card</span><span class="hljs-params">(String size, String color, <span class="hljs-type">int</span> index)</span> &#123;<br>        <span class="hljs-built_in">this</span>.size = size;<br>        <span class="hljs-built_in">this</span>.color = color;<br>        <span class="hljs-built_in">this</span>.index = index;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getSize</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> size;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setSize</span><span class="hljs-params">(String size)</span> &#123;<br>        <span class="hljs-built_in">this</span>.size = size;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getColor</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> color;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setColor</span><span class="hljs-params">(String color)</span> &#123;<br>        <span class="hljs-built_in">this</span>.color = color;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">getIndex</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> index;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setIndex</span><span class="hljs-params">(<span class="hljs-type">int</span> index)</span> &#123;<br>        <span class="hljs-built_in">this</span>.index = index;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">toString</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> size + color;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：斗地主游戏的案例开发。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    业务需求分析:</span><br><span class="hljs-comment">        斗地主的做牌, 洗牌, 发牌, 排序（拓展知识）, 看牌。</span><br><span class="hljs-comment">        业务: 总共有54张牌。</span><br><span class="hljs-comment">        点数: &quot;3&quot;,&quot;4&quot;,&quot;5&quot;,&quot;6&quot;,&quot;7&quot;,&quot;8&quot;,&quot;9&quot;,&quot;10&quot;,&quot;J&quot;,&quot;Q&quot;,&quot;K&quot;,&quot;A&quot;,&quot;2&quot;</span><br><span class="hljs-comment">        花色: &quot;♠&quot;, &quot;♥&quot;, &quot;♣&quot;, &quot;♦&quot;</span><br><span class="hljs-comment">        大小王: &quot;👲&quot; , &quot;🃏&quot;</span><br><span class="hljs-comment">        点数分别要组合4种花色，大小王各一张。</span><br><span class="hljs-comment">        斗地主：发出51张牌，剩下3张作为底牌。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    功能：</span><br><span class="hljs-comment">        1.做牌。</span><br><span class="hljs-comment">        2.洗牌。</span><br><span class="hljs-comment">        3.定义3个玩家</span><br><span class="hljs-comment">        4.发牌。</span><br><span class="hljs-comment">        5.排序（拓展，了解，作业）</span><br><span class="hljs-comment">        6.看牌</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">GameDemo</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">      1、定义一个静态的集合存储54张牌对象</span><br><span class="hljs-comment">     */</span><br>     <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> List&lt;Card&gt; allCards = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">      2、做牌：定义静态代码块初始化牌数据</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">static</span> &#123;<br>        <span class="hljs-comment">// 3、定义点数：个数确定，类型确定，使用数组</span><br>        String[] sizes = &#123;<span class="hljs-string">&quot;3&quot;</span>,<span class="hljs-string">&quot;4&quot;</span>,<span class="hljs-string">&quot;5&quot;</span>,<span class="hljs-string">&quot;6&quot;</span>,<span class="hljs-string">&quot;7&quot;</span>,<span class="hljs-string">&quot;8&quot;</span>,<span class="hljs-string">&quot;9&quot;</span>,<span class="hljs-string">&quot;10&quot;</span>,<span class="hljs-string">&quot;J&quot;</span>,<span class="hljs-string">&quot;Q&quot;</span>,<span class="hljs-string">&quot;K&quot;</span>,<span class="hljs-string">&quot;A&quot;</span>,<span class="hljs-string">&quot;2&quot;</span>&#125;;<br>        <span class="hljs-comment">// 4、定义花色：个数确定，类型确定，使用数组</span><br>        String[] colors = &#123;<span class="hljs-string">&quot;♠&quot;</span>, <span class="hljs-string">&quot;♥&quot;</span>, <span class="hljs-string">&quot;♣&quot;</span>, <span class="hljs-string">&quot;♦&quot;</span>&#125;;<br>        <span class="hljs-comment">// 5、组合点数和花色</span><br>        <span class="hljs-type">int</span> <span class="hljs-variable">index</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; <span class="hljs-comment">// 记录牌的大小</span><br>        <span class="hljs-keyword">for</span> (String size : sizes) &#123;<br>            index++;<br>            <span class="hljs-keyword">for</span> (String color : colors) &#123;<br>                <span class="hljs-comment">// 6、封装成一个牌对象。</span><br>                <span class="hljs-type">Card</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Card</span>(size, color, index);<br>                <span class="hljs-comment">// 7、存入到集合容器中去</span><br>                allCards.add(c);<br>            &#125;<br>        &#125;<br>        <span class="hljs-comment">// 8 大小王存入到集合对象中去 &quot;👲&quot; , &quot;🃏&quot;</span><br>        <span class="hljs-type">Card</span> <span class="hljs-variable">c1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Card</span>(<span class="hljs-string">&quot;&quot;</span> ,  <span class="hljs-string">&quot;🃏&quot;</span>, ++index);<br>        <span class="hljs-type">Card</span> <span class="hljs-variable">c2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Card</span>(<span class="hljs-string">&quot;&quot;</span> ,  <span class="hljs-string">&quot;👲&quot;</span>,++index);<br>        Collections.addAll(allCards , c1 , c2);<br>        System.out.println(<span class="hljs-string">&quot;新牌：&quot;</span> + allCards);<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 9、洗牌</span><br>        Collections.shuffle(allCards);<br>        System.out.println(<span class="hljs-string">&quot;洗牌后：&quot;</span> + allCards);<br><br>        <span class="hljs-comment">// 10、发牌（定义三个玩家，每个玩家的牌也是一个集合容器）</span><br>        List&lt;Card&gt; linhuchong = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        List&lt;Card&gt; jiumozhi = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        List&lt;Card&gt; renyingying = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br><br>        <span class="hljs-comment">// 11、开始发牌（从牌集合中发出51张牌给三个玩家，剩余3张作为底牌）</span><br>        <span class="hljs-comment">// allCards = [🃏, A♠, 5♥, 2♠, 2♣, Q♣, 👲, Q♠ ...</span><br>        <span class="hljs-comment">//    i        0  1   2   3   4   5    6  7      %  3</span><br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; allCards.size() - <span class="hljs-number">3</span>; i++) &#123;<br>            <span class="hljs-comment">// 先拿到当前牌对象</span><br>            <span class="hljs-type">Card</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> allCards.get(i);<br>            <span class="hljs-keyword">if</span>(i % <span class="hljs-number">3</span> == <span class="hljs-number">0</span>) &#123;<br>                <span class="hljs-comment">// 请阿冲接牌</span><br>                linhuchong.add(c);<br>            &#125;<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(i % <span class="hljs-number">3</span> == <span class="hljs-number">1</span>)&#123;<br>                <span class="hljs-comment">// 请阿鸠</span><br>                jiumozhi.add(c);<br>            &#125;<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(i % <span class="hljs-number">3</span> == <span class="hljs-number">2</span>)&#123;<br>                <span class="hljs-comment">// 请盈盈接牌</span><br>                renyingying.add(c);<br>            &#125;<br>        &#125;<br><br>        <span class="hljs-comment">// 12、拿到最后三张底牌(把最后三张牌截取成一个子集合)</span><br>        List&lt;Card&gt; lastThreeCards = allCards.subList(allCards.size() - <span class="hljs-number">3</span> , allCards.size());<br><br>        <span class="hljs-comment">// 13、给玩家的牌排序（从大到小 可以自己先试试怎么实现）</span><br>        sortCards(linhuchong);<br>        sortCards(jiumozhi);<br>        sortCards(renyingying);<br><br>        <span class="hljs-comment">// 14、输出玩家的牌：</span><br>        System.out.println(<span class="hljs-string">&quot;啊冲：&quot;</span> + linhuchong);<br>        System.out.println(<span class="hljs-string">&quot;啊鸠：&quot;</span> + jiumozhi);<br>        System.out.println(<span class="hljs-string">&quot;盈盈：&quot;</span> + renyingying);<br>        System.out.println(<span class="hljs-string">&quot;三张底牌：&quot;</span> + lastThreeCards);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       给牌排序</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> cards</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">sortCards</span><span class="hljs-params">(List&lt;Card&gt; cards)</span> &#123;<br>        <span class="hljs-comment">// cards = [J♥, A♦, 3♥, 🃏, 5♦, Q♥, 2♥</span><br>        Collections.sort(cards, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Comparator</span>&lt;Card&gt;() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">compare</span><span class="hljs-params">(Card o1, Card o2)</span> &#123;<br>                <span class="hljs-comment">// o1 = J♥</span><br>                <span class="hljs-comment">// o2 = A♦</span><br>                <span class="hljs-comment">// 知道牌的大小，才可以指定规则</span><br>                <span class="hljs-keyword">return</span> o2.getIndex() - o1.getIndex();<br>            &#125;<br>        &#125;);<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="map集合">Map集合</h4>
<h6 id="map集合概述和使用">Map集合概述和使用</h6>
<ul>
<li>Map集合是一种双列集合，每个元素包含两个数据。</li>
<li>Map集合的每个元素的格式：key=value（键值对元素）。</li>
<li>Map集合也被称为“键值对集合”。</li>
</ul>
<h6 id="map集合整体格式">Map集合整体格式：</h6>
<ul>
<li>Collection集合的格式：[元素1，元素2，元素3.]</li>
<li>Map集合的完整格式：{key1=value1,key2=value2,key3=value.3,…</li>
</ul>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220426154833924.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="map集合体系特点">Map集合体系特点</h6>
<ul>
<li>Map集合的特点都是由键决定的。</li>
<li>Map集合的键是无序，不重复的，无索引的，值不做要求（可以重复）。</li>
<li>Map集合后面重复的键对应的值会覆盖前面重复键的值。</li>
<li>Map集合的键值对都可以为nul.</li>
</ul>
<h6 id="map集合实现类特点">Map集合实现类特点</h6>
<ul>
<li><p>HashMap:元素按照键是无序，不重复，无索引，值不做要求。(与Map体系一致)</p></li>
<li><p>LinkedHashMap:元素按照键是有序，不重复，无索引，值不做要求。</p>
<p>原理：底层数据结构是依然哈希表，只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。</p></li>
<li><p>TreeMap:元素按照建是排序，不重复，无索引的，值不做要求。</p></li>
</ul>
<h6 id="map常用api">Map常用API</h6>
<table>
<colgroup>
<col style="width: 49%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>V put(K key,V value)</td>
<td>添加元素</td>
</tr>
<tr class="even">
<td>V remove(Object key)</td>
<td>根据键删除键值对元素</td>
</tr>
<tr class="odd">
<td>void clear()</td>
<td>移除所有的键值对元素</td>
</tr>
<tr class="even">
<td>boolean containsKey(Object key)</td>
<td>判断集合是否包含指定的键</td>
</tr>
<tr class="odd">
<td>boolean containsValue(Object value)</td>
<td>判断集合是否包含指定的值</td>
</tr>
<tr class="even">
<td>boolean isEmpty()</td>
<td>判断集合是否为空</td>
</tr>
<tr class="odd">
<td>int size()</td>
<td>集合的长度，也就是集合中键值对的个数</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Map集合的常用API(重点中的重点)</span><br><span class="hljs-comment">     - public V put(K key, V value):  把指定的键与指定的值添加到Map集合中。</span><br><span class="hljs-comment">     - public V remove(Object key): 把指定的键 所对应的键值对元素 在Map集合中删除，返回被删除元素的值。</span><br><span class="hljs-comment">     - public V get(Object key) 根据指定的键，在Map集合中获取对应的值。</span><br><span class="hljs-comment">     - public Set&lt;K&gt; keySet(): 获取Map集合中所有的键，存储到Set集合中。</span><br><span class="hljs-comment">     - public Set&lt;Map.Entry&lt;K,V&gt;&gt; entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)。</span><br><span class="hljs-comment">     - public boolean containKey(Object key):判断该集合中是否有此键。</span><br><span class="hljs-comment">     - public boolean containValue(Object value):判断该集合中是否有此值。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1.添加元素: 无序，不重复，无索引。</span><br>        Map&lt;String , Integer&gt; maps = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        maps.put(<span class="hljs-string">&quot;iphoneX&quot;</span>,<span class="hljs-number">10</span>);<br>        maps.put(<span class="hljs-string">&quot;娃娃&quot;</span>,<span class="hljs-number">20</span>);<br>        maps.put(<span class="hljs-string">&quot;iphoneX&quot;</span>,<span class="hljs-number">100</span>);<span class="hljs-comment">//  Map集合后面重复的键对应的元素会覆盖前面重复的整个元素！</span><br>        maps.put(<span class="hljs-string">&quot;huawei&quot;</span>,<span class="hljs-number">100</span>);<br>        maps.put(<span class="hljs-string">&quot;生活用品&quot;</span>,<span class="hljs-number">10</span>);<br>        maps.put(<span class="hljs-string">&quot;手表&quot;</span>,<span class="hljs-number">10</span>);<br>        <span class="hljs-comment">// &#123;huawei=100, 手表=10, 生活用品=10, iphoneX=100, 娃娃=20&#125;</span><br>        System.out.println(maps);<br><br>        <span class="hljs-comment">// 2.清空集合</span><br><span class="hljs-comment">//        maps.clear();</span><br><span class="hljs-comment">//        System.out.println(maps);</span><br><br>        <span class="hljs-comment">// 3.判断集合是否为空，为空返回true ,反之！</span><br>        System.out.println(maps.isEmpty());<br><br>        <span class="hljs-comment">// 4.根据键获取对应值:public V get(Object key)</span><br>        <span class="hljs-type">Integer</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> maps.get(<span class="hljs-string">&quot;huawei&quot;</span>);<br>        System.out.println(key);<br>        System.out.println(maps.get(<span class="hljs-string">&quot;生活用品&quot;</span>)); <span class="hljs-comment">// 10</span><br>        System.out.println(maps.get(<span class="hljs-string">&quot;生活用品2&quot;</span>)); <span class="hljs-comment">// null</span><br><br>        <span class="hljs-comment">// 5.根据键删除整个元素。(删除键会返回键的值)</span><br>        System.out.println(maps.remove(<span class="hljs-string">&quot;iphoneX&quot;</span>));<br>        System.out.println(maps);<br><br>        <span class="hljs-comment">// 6.判断是否包含某个键 ，包含返回true ,反之</span><br>        System.out.println(maps.containsKey(<span class="hljs-string">&quot;娃娃&quot;</span>));  <span class="hljs-comment">// true</span><br>        System.out.println(maps.containsKey(<span class="hljs-string">&quot;娃娃2&quot;</span>));  <span class="hljs-comment">// false</span><br>        System.out.println(maps.containsKey(<span class="hljs-string">&quot;iphoneX&quot;</span>)); <span class="hljs-comment">// false</span><br><br>        <span class="hljs-comment">// 7.判断是否包含某个值。</span><br>        System.out.println(maps.containsValue(<span class="hljs-number">100</span>));  <span class="hljs-comment">//</span><br>        System.out.println(maps.containsValue(<span class="hljs-number">10</span>));  <span class="hljs-comment">//</span><br>        System.out.println(maps.containsValue(<span class="hljs-number">22</span>)); <span class="hljs-comment">//</span><br><br>        <span class="hljs-comment">// &#123;huawei=100, 手表=10, 生活用品=10, 娃娃=20&#125;</span><br>        <span class="hljs-comment">// 8.获取全部键的集合：public Set&lt;K&gt; keySet()</span><br>        Set&lt;String&gt; keys = maps.keySet();<br>        System.out.println(keys);<br><br>        System.out.println(<span class="hljs-string">&quot;------------------------------&quot;</span>);<br>        <span class="hljs-comment">// 9.获取全部值的集合：Collection&lt;V&gt; values();</span><br>        Collection&lt;Integer&gt; values = maps.values();<br>        System.out.println(values);<br><br>        <span class="hljs-comment">// 10.集合的大小</span><br>        System.out.println(maps.size()); <span class="hljs-comment">// 4</span><br><br>        <span class="hljs-comment">// 11.合并其他Map集合。(拓展)</span><br>        Map&lt;String , Integer&gt; map1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        map1.put(<span class="hljs-string">&quot;java1&quot;</span>, <span class="hljs-number">1</span>);<br>        map1.put(<span class="hljs-string">&quot;java2&quot;</span>, <span class="hljs-number">100</span>);<br>        Map&lt;String , Integer&gt; map2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        map2.put(<span class="hljs-string">&quot;java2&quot;</span>, <span class="hljs-number">1</span>);<br>        map2.put(<span class="hljs-string">&quot;java3&quot;</span>, <span class="hljs-number">100</span>);<br>        map1.putAll(map2); <span class="hljs-comment">// 把集合map2的元素拷贝一份到map1中去</span><br>        System.out.println(map1);<br>        System.out.println(map2);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="map三种遍历方式">Map三种遍历方式</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Map集合的遍历方式一：键找值</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Map集合的遍历方式有：3种。</span><br><span class="hljs-comment">        （1）“键找值”的方式遍历：先获取Map集合全部的键，再根据遍历键找值。</span><br><span class="hljs-comment">        （2）“键值对”的方式遍历：难度较大。</span><br><span class="hljs-comment">        （3）JDK 1.8开始之后的新技术：Lambda表达式。（暂时了解）</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    a.“键找值”的方式遍历Map集合。</span><br><span class="hljs-comment">        1.先获取Map集合的全部键的Set集合。</span><br><span class="hljs-comment">        2.遍历键的Set集合，然后通过键找值。</span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">        代码简单，需要记住!</span><br><span class="hljs-comment"></span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapDemo01</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        Map&lt;String , Integer&gt; maps = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        <span class="hljs-comment">// 1.添加元素: 无序，不重复，无索引。</span><br>        maps.put(<span class="hljs-string">&quot;娃娃&quot;</span>,<span class="hljs-number">30</span>);<br>        maps.put(<span class="hljs-string">&quot;iphoneX&quot;</span>,<span class="hljs-number">100</span>);<br>        maps.put(<span class="hljs-string">&quot;huawei&quot;</span>,<span class="hljs-number">1000</span>);<br>        maps.put(<span class="hljs-string">&quot;生活用品&quot;</span>,<span class="hljs-number">10</span>);<br>        maps.put(<span class="hljs-string">&quot;手表&quot;</span>,<span class="hljs-number">10</span>);<br>        System.out.println(maps);<br>        <span class="hljs-comment">// maps = &#123;huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30&#125;</span><br><br>        <span class="hljs-comment">// 1、键找值：第一步：先拿到集合的全部键。</span><br>        Set&lt;String&gt; keys = maps.keySet();<br>        <span class="hljs-comment">// 2、第二步：遍历每个键，根据键提取值</span><br>        <span class="hljs-keyword">for</span> (String key : keys) &#123;<br>            <span class="hljs-type">int</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> maps.get(key);<br>            System.out.println(key + <span class="hljs-string">&quot;===&gt;&quot;</span> + value);<br>        &#125;<br><br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Map集合的遍历方式。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Map集合的遍历方式有：3种。</span><br><span class="hljs-comment">        （1）“键找值”的方式遍历：先获取Map集合全部的键，再根据键找值。</span><br><span class="hljs-comment">        （2）“键值对”的方式遍历：难度较大。</span><br><span class="hljs-comment">        （3）JDK 1.8开始之后的新技术：Lambda表达式。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    b.“键值对”的方式遍历：</span><br><span class="hljs-comment">        1.把Map集合转换成一个Set集合:Set&lt;Map.Entry&lt;K, V&gt;&gt; entrySet();</span><br><span class="hljs-comment">        2.此时键值对元素的类型就确定了，类型是键值对实体类型：Map.Entry&lt;K, V&gt;</span><br><span class="hljs-comment">        3.接下来就可以用foreach遍历这个Set集合，类型用Map.Entry&lt;K, V&gt;</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        Map&lt;String , Integer&gt; maps = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        <span class="hljs-comment">// 1.添加元素: 无序，不重复，无索引。</span><br>        maps.put(<span class="hljs-string">&quot;娃娃&quot;</span>,<span class="hljs-number">30</span>);<br>        maps.put(<span class="hljs-string">&quot;iphoneX&quot;</span>,<span class="hljs-number">100</span>);<br>        maps.put(<span class="hljs-string">&quot;huawei&quot;</span>,<span class="hljs-number">1000</span>);<br>        maps.put(<span class="hljs-string">&quot;生活用品&quot;</span>,<span class="hljs-number">10</span>);<br>        maps.put(<span class="hljs-string">&quot;手表&quot;</span>,<span class="hljs-number">10</span>);<br>        System.out.println(maps);<br>        <span class="hljs-comment">// maps = &#123;huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30&#125;</span><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">            maps = &#123;huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30&#125;</span><br><span class="hljs-comment">                👇</span><br><span class="hljs-comment">            使用foreach遍历map集合.发现Map集合的键值对元素直接是没有类型的。所以不可以直接foreach遍历集合。</span><br><span class="hljs-comment">                👇</span><br><span class="hljs-comment">            可以通过调用Map的方法 entrySet把Map集合转换成Set集合形式  maps.entrySet();</span><br><span class="hljs-comment">                👇</span><br><span class="hljs-comment">            Set&lt;Map.Entry&lt;String,Integer&gt;&gt; entries =  maps.entrySet();</span><br><span class="hljs-comment">             [(huawei=1000), (手表=10), (生活用品=10), (iphoneX=100), (娃娃=30)]</span><br><span class="hljs-comment">                              entry</span><br><span class="hljs-comment">                👇</span><br><span class="hljs-comment">            此时可以使用foreach遍历</span><br><span class="hljs-comment">       */</span><br>       <span class="hljs-comment">// 1、把Map集合转换成Set集合</span><br>        Set&lt;Map.Entry&lt;String, Integer&gt;&gt; entries = maps.entrySet();<br>        <span class="hljs-comment">// 2、开始遍历</span><br>        <span class="hljs-keyword">for</span>(Map.Entry&lt;String, Integer&gt; entry : entries)&#123;<br>            <span class="hljs-type">String</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> entry.getKey();<br>            <span class="hljs-type">int</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> entry.getValue();<br>            System.out.println(key + <span class="hljs-string">&quot;====&gt;&quot;</span> + value);<br>        &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Map集合的遍历方式。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Map集合的遍历方式有：3种。</span><br><span class="hljs-comment">        （1）“键找值”的方式遍历：先获取Map集合全部的键，再根据键找值。</span><br><span class="hljs-comment">        （2）“键值对”的方式遍历：难度较大。</span><br><span class="hljs-comment">        （3）JDK 1.8开始之后的新技术：Lambda表达式。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    c.JDK 1.8开始之后的新技术：Lambda表达式。（暂时了解）</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapDemo03</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        Map&lt;String , Integer&gt; maps = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        <span class="hljs-comment">// 1.添加元素: 无序，不重复，无索引。</span><br>        maps.put(<span class="hljs-string">&quot;娃娃&quot;</span>,<span class="hljs-number">30</span>);<br>        maps.put(<span class="hljs-string">&quot;iphoneX&quot;</span>,<span class="hljs-number">100</span>);<span class="hljs-comment">//  Map集合后面重复的键对应的元素会覆盖前面重复的整个元素！</span><br>        maps.put(<span class="hljs-string">&quot;huawei&quot;</span>,<span class="hljs-number">1000</span>);<br>        maps.put(<span class="hljs-string">&quot;生活用品&quot;</span>,<span class="hljs-number">10</span>);<br>        maps.put(<span class="hljs-string">&quot;手表&quot;</span>,<span class="hljs-number">10</span>);<br>        System.out.println(maps);<br><br>        <span class="hljs-comment">//  maps = &#123;huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30&#125;</span><br><br><span class="hljs-comment">//        maps.forEach(new BiConsumer&lt;String, Integer&gt;() &#123;</span><br><span class="hljs-comment">//            @Override</span><br><span class="hljs-comment">//            public void accept(String key, Integer value) &#123;</span><br><span class="hljs-comment">//                System.out.println(key + &quot;---&gt;&quot; + value);</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;);</span><br><br>        maps.forEach((k, v) -&gt; &#123;<br>                System.out.println(k + <span class="hljs-string">&quot;---&gt;&quot;</span> + v);<br>        &#125;);<br><br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<p><strong>需求</strong>
某个班级80名学生，现在需要组成秋游活动，班长提供了四个景点依次是(A、B、C、D),每个学生只能选择一个景点，请统计出最终哪个景点想去的人数最多。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapTest1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>         <span class="hljs-comment">// 1、把80个学生选择的数据拿进来。</span><br>        String[] selects = &#123;<span class="hljs-string">&quot;A&quot;</span> , <span class="hljs-string">&quot;B&quot;</span>, <span class="hljs-string">&quot;C&quot;</span>, <span class="hljs-string">&quot;D&quot;</span>&#125;;<br>        <span class="hljs-type">StringBuilder</span> <span class="hljs-variable">sb</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">StringBuilder</span>();<br>        <span class="hljs-type">Random</span> <span class="hljs-variable">r</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Random</span>();<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">80</span>; i++) &#123;<br>            sb.append(selects[r.nextInt(selects.length)]);<br>        &#125;<br>        System.out.println(sb);<br><br>        <span class="hljs-comment">// 2、定义一个Map集合记录最终统计的结果： A=30 B=20 C=20 D=10  键是景点 值是选择的数量</span><br>        Map&lt;Character, Integer&gt; infos = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;(); <span class="hljs-comment">//</span><br><br>        <span class="hljs-comment">// 3、遍历80个学生选择的数据</span><br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; sb.length(); i++) &#123;<br>            <span class="hljs-comment">// 4、提取当前选择景点字符</span><br>            <span class="hljs-type">char</span> <span class="hljs-variable">ch</span> <span class="hljs-operator">=</span> sb.charAt(i);<br>            <span class="hljs-comment">// 5、判断Map集合中是否存在这个键</span><br>            <span class="hljs-keyword">if</span>(infos.containsKey(ch))&#123;<br>                 <span class="hljs-comment">// 让其值 + 1</span><br>                infos.put(ch , infos.get(ch) + <span class="hljs-number">1</span>);<br>            &#125;<span class="hljs-keyword">else</span> &#123;<br>                <span class="hljs-comment">// 说明此景点是第一次被选</span><br>                infos.put(ch , <span class="hljs-number">1</span>);<br>            &#125;<br>        &#125;<br><br>        <span class="hljs-comment">// 4、输出集合</span><br>        System.out.println(infos);<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="集合嵌套">集合嵌套</h6>
<p>某个班级多名学生，现在需要组成秋游活动，班长提供了四个景点依次是(A、B、C、D),每个学生可以选择多个景点，请统计出最终哪个景点想去的人数最多。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapTest4</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、要求程序记录每个学生选择的情况。</span><br>        <span class="hljs-comment">// 使用一个Map集合存储。</span><br>        Map&lt;String, List&lt;String&gt;&gt; data = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br><br>        <span class="hljs-comment">// 2、把学生选择的数据存入进去。</span><br>        List&lt;String&gt; selects = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        Collections.addAll(selects, <span class="hljs-string">&quot;A&quot;</span>, <span class="hljs-string">&quot;C&quot;</span>);<br>        data.put(<span class="hljs-string">&quot;罗勇&quot;</span>, selects);<br><br>        List&lt;String&gt; selects1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        Collections.addAll(selects1, <span class="hljs-string">&quot;B&quot;</span>, <span class="hljs-string">&quot;C&quot;</span> , <span class="hljs-string">&quot;D&quot;</span>);<br>        data.put(<span class="hljs-string">&quot;胡涛&quot;</span>, selects1);<br><br>        List&lt;String&gt; selects2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        Collections.addAll(selects2 , <span class="hljs-string">&quot;A&quot;</span>,  <span class="hljs-string">&quot;B&quot;</span>, <span class="hljs-string">&quot;C&quot;</span> , <span class="hljs-string">&quot;D&quot;</span>);<br>        data.put(<span class="hljs-string">&quot;刘军&quot;</span>, selects2);<br><br>        System.out.println(data);<br><br>        <span class="hljs-comment">// 3、统计每个景点选择的人数。</span><br>        Map&lt;String, Integer&gt; infos = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;(); <span class="hljs-comment">// &#123;&#125;</span><br><br>        <span class="hljs-comment">// 4、提取所有人选择的景点的信息。</span><br>        Collection&lt;List&lt;String&gt;&gt; values = data.values();<br>        System.out.println(values);<br>        <span class="hljs-comment">// values = [[A, B, C, D], [B, C, D], [A, C]]</span><br>        <span class="hljs-comment">//             value</span><br><br>        <span class="hljs-keyword">for</span> (List&lt;String&gt; value : values) &#123;<br>            <span class="hljs-keyword">for</span> (String s : value) &#123;<br>                <span class="hljs-comment">// 有没有包含这个景点</span><br>                <span class="hljs-keyword">if</span>(infos.containsKey(s))&#123;<br>                    infos.put(s, infos.get(s) + <span class="hljs-number">1</span>);<br>                &#125;<span class="hljs-keyword">else</span> &#123;<br>                    infos.put(s , <span class="hljs-number">1</span>);<br>                &#125;<br>            &#125;<br>        &#125;<br><br>        System.out.println(infos);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="stream异常体系日志框架">Stream、异常体系、日志框架</h4>
<h6 id="不可变集合">不可变集合</h6>
<p>定义</p>
<p>不可变集合，就是不可被修改的集合。
集合的数据项在创建的时候提供，并且在整个生命周期中都不可改变。否则报错。</p>
<p>如果某个数据不能被修改，把它防御性地拷贝到不可变集合中是个很好的实践。
或者当集合对象被不可信的库调用时，不可变形式是安全的。</p>
<table>
<colgroup>
<col style="width: 54%" />
<col style="width: 45%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>static <E> List<E> of(E…elements)</td>
<td>创建一个具有指定元素的List集合对象</td>
</tr>
<tr class="even">
<td>static <E> Set<E> of(E…elements)</td>
<td>创建一个具有指定元素的Set集合对象</td>
</tr>
<tr class="odd">
<td>static &lt;K , V&gt; Map&lt;K，V&gt; of(E…elements)</td>
<td>创建一个具有指定元素的Map集合对象</td>
</tr>
</tbody>
</table>
<h6 id="stream流">Stream流</h6>
<p>在Java8中，得益于Lambda所带来的函数式编程，引入了一个全新Stream流概念。
目的：用于简化集合和数组操作的API。</p>
<p>初体验-&gt;对比</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">StreamTest</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        List&lt;String&gt; names = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        Collections.addAll(names, <span class="hljs-string">&quot;张三丰&quot;</span>,<span class="hljs-string">&quot;张无忌&quot;</span>,<span class="hljs-string">&quot;周芷若&quot;</span>,<span class="hljs-string">&quot;赵敏&quot;</span>,<span class="hljs-string">&quot;张强&quot;</span>);<br>        System.out.println(names);<br><span class="hljs-comment">//</span><br><span class="hljs-comment">//        // 1、从集合中找出姓张的放到新集合</span><br><span class="hljs-comment">//        List&lt;String&gt; zhangList = new ArrayList&lt;&gt;();</span><br><span class="hljs-comment">//        for (String name : names) &#123;</span><br><span class="hljs-comment">//            if(name.startsWith(&quot;张&quot;))&#123;</span><br><span class="hljs-comment">//                zhangList.add(name);</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;</span><br><span class="hljs-comment">//        System.out.println(zhangList);</span><br><span class="hljs-comment">//</span><br><span class="hljs-comment">//        // 2、找名称长度是3的姓名</span><br><span class="hljs-comment">//        List&lt;String&gt; zhangThreeList = new ArrayList&lt;&gt;();</span><br><span class="hljs-comment">//        for (String name : zhangList) &#123;</span><br><span class="hljs-comment">//            if(name.length() == 3)&#123;</span><br><span class="hljs-comment">//                zhangThreeList.add(name);</span><br><span class="hljs-comment">//            &#125;</span><br><span class="hljs-comment">//        &#125;</span><br><span class="hljs-comment">//        System.out.println(zhangThreeList);</span><br><br>        <span class="hljs-comment">// 3、使用Stream实现的</span><br>        names.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>)).filter(s -&gt; s.length() == <span class="hljs-number">3</span>).forEach(s -&gt; System.out.println(s));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>1、Stream流的作用是什么，结合了什么技术？
简化集合、数组操作的API。结合了Lambda表达式。
2、说说Stream流的思想和使用步骤。
先得到集合或者数组的Stream流（就是一根传送带）。 把元素放上去。
然后就用这个Stream流简化的API来方便的操作元素。</p>
<h6 id="stream流的三类方法">Stream流的三类方法</h6>
<ul>
<li><p>获取Stream流</p>
<p>创建一条流水线，并把数据放到流水线上准备进行操作</p></li>
<li><p>中间方法</p>
<p>流水线上的操作。一次操作完毕之后，还可以继续进行其他操作。</p></li>
<li><p>终结方法</p>
<p>一个Stream流只能有一个终结方法，是流水线上的最后一个操作</p></li>
</ul>
<h6 id="集合获取stream流的方式">集合获取Stream流的方式</h6>
<p>可以使用Collection接口中的默认方法stream()生成流</p>
<table>
<thead>
<tr class="header">
<th>名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>default Stream<E> stream()</td>
<td>获取当前集合对象的Stream流</td>
</tr>
</tbody>
</table>
<h6 id="数组获取stream流的方式">数组获取Stream流的方式</h6>
<table>
<colgroup>
<col style="width: 61%" />
<col style="width: 38%" />
</colgroup>
<thead>
<tr class="header">
<th>名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public static <T> Stream<T> stream(T[] array)</td>
<td>获取当前数组的Stream流</td>
</tr>
<tr class="even">
<td>public static<T> Stream<T> of(T... values)</td>
<td>获取当前数组/可变数据的Stream流</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：Stream流的获取</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     Stream流式思想的核心：</span><br><span class="hljs-comment">                 是先得到集合或者数组的Stream流（就是一根传送带）</span><br><span class="hljs-comment">                 然后就用这个Stream流操作集合或者数组的元素。</span><br><span class="hljs-comment">                 然后用Stream流简化替代集合操作的API.</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     集合获取流的API:</span><br><span class="hljs-comment">         (1) default Stream&lt;E&gt; stream();</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">         集合获取Stream流用: stream();</span><br><span class="hljs-comment">         数组：Arrays.stream(数组)   /  Stream.of(数组);</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">StreamDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">/** --------------------Collection集合获取流-------------------------------   */</span><br>        Collection&lt;String&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        Stream&lt;String&gt; s =  list.stream();<br><br>        <span class="hljs-comment">/** --------------------Map集合获取流-------------------------------   */</span><br>        Map&lt;String, Integer&gt; maps = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span>&lt;&gt;();<br>        <span class="hljs-comment">// 键流</span><br>        Stream&lt;String&gt; keyStream = maps.keySet().stream();<br>        <span class="hljs-comment">// 值流</span><br>        Stream&lt;Integer&gt; valueStream = maps.values().stream();<br>        <span class="hljs-comment">// 键值对流（拿整体）</span><br>        Stream&lt;Map.Entry&lt;String,Integer&gt;&gt; keyAndValueStream =  maps.entrySet().stream();<br><br>        <span class="hljs-comment">/** ---------------------数组获取流------------------------------   */</span><br>        String[] names = &#123;<span class="hljs-string">&quot;赵敏&quot;</span>,<span class="hljs-string">&quot;小昭&quot;</span>,<span class="hljs-string">&quot;灭绝&quot;</span>,<span class="hljs-string">&quot;周芷若&quot;</span>&#125;;<br>        Stream&lt;String&gt; nameStream = Arrays.stream(names);<br>        Stream&lt;String&gt; nameStream2 = Stream.of(names);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="stream常用api">Stream常用API</h6>
<table>
<colgroup>
<col style="width: 53%" />
<col style="width: 46%" />
</colgroup>
<thead>
<tr class="header">
<th>名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Stream<T> filter(Predicate&lt;? super T&gt; predicate)</td>
<td>用于对流中的数据进行<strong>过滤。</strong></td>
</tr>
<tr class="even">
<td>Stream<T> limit(long maxSize)</td>
<td>获取前几个元素</td>
</tr>
<tr class="odd">
<td>Stream<T> skip(long n)</td>
<td>跳过前几个元素</td>
</tr>
<tr class="even">
<td>Stream<T> distinct()</td>
<td>去除流中重复的元素。依赖(hashCode和equals方法)</td>
</tr>
<tr class="odd">
<td>static <T> Stream<T> concat(Stream a, Stream b)</td>
<td><strong>合并</strong>a和b两个流为一个流</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：Stream流的常用API</span><br><span class="hljs-comment">         forEach : 逐一处理(遍历)</span><br><span class="hljs-comment">         count：统计个数</span><br><span class="hljs-comment">            -- long count();</span><br><span class="hljs-comment">         filter : 过滤元素</span><br><span class="hljs-comment">            -- Stream&lt;T&gt; filter(Predicate&lt;? super T&gt; predicate)</span><br><span class="hljs-comment">         limit : 取前几个元素</span><br><span class="hljs-comment">         skip : 跳过前几个</span><br><span class="hljs-comment">         map : 加工方法</span><br><span class="hljs-comment">         concat : 合并流。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">StreamDemo03</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        List&lt;String&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        list.add(<span class="hljs-string">&quot;张无忌&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;周芷若&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;赵敏&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;张强&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;张三丰&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;张三丰&quot;</span>);<br><br>        <span class="hljs-comment">// Stream&lt;T&gt; filter(Predicate&lt;? super T&gt; predicate)</span><br>        list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>)).forEach(s -&gt; System.out.println(s));<br><br>        <span class="hljs-type">long</span> <span class="hljs-variable">size</span> <span class="hljs-operator">=</span> list.stream().filter(s -&gt; s.length() == <span class="hljs-number">3</span>).count();<br>        System.out.println(size);<br><br>       <span class="hljs-comment">// list.stream().filter(s -&gt; s.startsWith(&quot;张&quot;)).limit(2).forEach(s -&gt; System.out.println(s));</span><br>        list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>)).limit(<span class="hljs-number">2</span>).forEach(System.out::println);<br><br>        list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>)).skip(<span class="hljs-number">2</span>).forEach(System.out::println);<br><br>        <span class="hljs-comment">// map加工方法: 第一个参数原材料  -&gt; 第二个参数是加工后的结果。</span><br>        <span class="hljs-comment">// 给集合元素的前面都加上一个：黑马的：</span><br>        list.stream().map(s -&gt; <span class="hljs-string">&quot;黑马的：&quot;</span> + s).forEach(a -&gt; System.out.println(a));<br><br>        <span class="hljs-comment">// 需求：把所有的名称 都加工成一个学生对象。</span><br>         list.stream().map(s -&gt; <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(s)).forEach(s -&gt; System.out.println(s));<br><span class="hljs-comment">//        list.stream().map(Student::new).forEach(System.out::println); // 构造器引用  方法引用</span><br><br>        <span class="hljs-comment">// 合并流。</span><br>        Stream&lt;String&gt; s1 = list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>));<br>        Stream&lt;String&gt; s2 = Stream.of(<span class="hljs-string">&quot;java1&quot;</span>, <span class="hljs-string">&quot;java2&quot;</span>);<br>        <span class="hljs-comment">// public static &lt;T&gt; Stream&lt;T&gt; concat(Stream&lt;? extends T&gt; a, Stream&lt;? extends T&gt; b)</span><br>        Stream&lt;String&gt; s3 = Stream.concat(s1 , s2);<br>        s3.distinct().forEach(s -&gt; System.out.println(s));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="综合案例">综合案例</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">StreamDemo04</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">double</span> allMoney ;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">double</span> allMoney2 ; <span class="hljs-comment">// 2个部门去掉最高工资，最低工资的总和</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        List&lt;Employee&gt; one = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        one.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;猪八戒&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">30000</span> , <span class="hljs-number">25000</span>, <span class="hljs-literal">null</span>));<br>        one.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;孙悟空&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">25000</span> , <span class="hljs-number">1000</span>, <span class="hljs-string">&quot;顶撞上司&quot;</span>));<br>        one.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;沙僧&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">20000</span> , <span class="hljs-number">20000</span>, <span class="hljs-literal">null</span>));<br>        one.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;小白龙&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">20000</span> , <span class="hljs-number">25000</span>, <span class="hljs-literal">null</span>));<br><br>        List&lt;Employee&gt; two = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        two.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;武松&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">15000</span> , <span class="hljs-number">9000</span>, <span class="hljs-literal">null</span>));<br>        two.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;李逵&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">20000</span> , <span class="hljs-number">10000</span>, <span class="hljs-literal">null</span>));<br>        two.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;西门庆&quot;</span>,<span class="hljs-string">&#x27;男&#x27;</span>,<span class="hljs-number">50000</span> , <span class="hljs-number">100000</span>, <span class="hljs-string">&quot;被打&quot;</span>));<br>        two.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;潘金莲&quot;</span>,<span class="hljs-string">&#x27;女&#x27;</span>,<span class="hljs-number">3500</span> , <span class="hljs-number">1000</span>, <span class="hljs-string">&quot;被打&quot;</span>));<br>        two.add(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">&quot;武大郎&quot;</span>,<span class="hljs-string">&#x27;女&#x27;</span>,<span class="hljs-number">20000</span> , <span class="hljs-number">0</span>, <span class="hljs-string">&quot;下毒&quot;</span>));<br><br>        <span class="hljs-comment">// 1、开发一部的最高工资的员工。（API）</span><br>        <span class="hljs-comment">// 指定大小规则了</span><br><span class="hljs-comment">//        Employee e = one.stream().max((e1, e2) -&gt; Double.compare(e1.getSalary() + e1.getBonus(),  e2.getSalary() + e2.getBonus()))</span><br><span class="hljs-comment">//                .get();</span><br><span class="hljs-comment">//       System.out.println(e);</span><br>        <span class="hljs-type">Topperformer</span> <span class="hljs-variable">t</span> <span class="hljs-operator">=</span> one.stream().max((e1, e2) -&gt; Double.compare(e1.getSalary() + e1.getBonus(),  e2.getSalary() + e2.getBonus()))<br>                .map(e -&gt; <span class="hljs-keyword">new</span> <span class="hljs-title class_">Topperformer</span>(e.getName(),  e.getSalary() + e.getBonus())).get();<br>        System.out.println(t);<br><br>        <span class="hljs-comment">// 2、统计平均工资，去掉最高工资和最低工资</span><br>        one.stream().sorted((e1, e2) -&gt; Double.compare(e1.getSalary() + e1.getBonus(),  e2.getSalary() + e2.getBonus()))<br>                .skip(<span class="hljs-number">1</span>).limit(one.size() - <span class="hljs-number">2</span>).forEach(e -&gt; &#123;<br>                    <span class="hljs-comment">// 求出总和：剩余员工的工资总和</span><br>            allMoney += (e.getSalary() + e.getBonus());<br>        &#125;);<br>        System.out.println(<span class="hljs-string">&quot;开发一部的平均工资是：&quot;</span> + allMoney / (one.size() - <span class="hljs-number">2</span>));<br><br>        <span class="hljs-comment">// 3、合并2个集合流，再统计</span><br>        Stream&lt;Employee&gt; s1 = one.stream();<br>        Stream&lt;Employee&gt; s2 = two.stream();<br>        Stream&lt;Employee&gt; s3 = Stream.concat(s1 , s2);<br>        s3.sorted((e1, e2) -&gt; Double.compare(e1.getSalary() + e1.getBonus(),  e2.getSalary() + e2.getBonus()))<br>                .skip(<span class="hljs-number">1</span>).limit(one.size() + two.size() - <span class="hljs-number">2</span>).forEach(e -&gt; &#123;<br>            <span class="hljs-comment">// 求出总和：剩余员工的工资总和</span><br>            allMoney2 += (e.getSalary() + e.getBonus());<br>        &#125;);<br><br>        <span class="hljs-comment">// BigDecimal</span><br>        <span class="hljs-type">BigDecimal</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> BigDecimal.valueOf(allMoney2);<br>        <span class="hljs-type">BigDecimal</span> <span class="hljs-variable">b</span> <span class="hljs-operator">=</span> BigDecimal.valueOf(one.size()  + two.size() - <span class="hljs-number">2</span>);<br>        System.out.println(<span class="hljs-string">&quot;开发部的平均工资是：&quot;</span> + a.divide(b,<span class="hljs-number">2</span>, RoundingMode.HALF_UP));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="收集stream流">收集Stream流</h6>
<p><strong>收集Stream流的含义</strong>：就是把Stream流操作后的结果数据转回到集合或者数组中去。</p>
<p>Stream流：方便操作集合/数组的<strong>手段。</strong></p>
<p>集合/数组：才是开发中的<strong>目的</strong>。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">StreamDemo05</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        List&lt;String&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        list.add(<span class="hljs-string">&quot;张无忌&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;周芷若&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;赵敏&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;张强&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;张三丰&quot;</span>);<br>        list.add(<span class="hljs-string">&quot;张三丰&quot;</span>);<br><br>        Stream&lt;String&gt; s1 = list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>));<br>        List&lt;String&gt; zhangList = s1.collect(Collectors.toList()); <span class="hljs-comment">// 可变集合</span><br>        zhangList.add(<span class="hljs-string">&quot;java1&quot;</span>);<br>        System.out.println(zhangList);<br><br><span class="hljs-comment">//       List&lt;String&gt; list1 = s1.toList(); // 得到不可变集合</span><br><span class="hljs-comment">//       list1.add(&quot;java&quot;);</span><br><span class="hljs-comment">//       System.out.println(list1);</span><br><br>        <span class="hljs-comment">// 注意注意注意：“流只能使用一次”</span><br>        Stream&lt;String&gt; s2 = list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>));<br>        Set&lt;String&gt; zhangSet = s2.collect(Collectors.toSet());<br>        System.out.println(zhangSet);<br><br>        Stream&lt;String&gt; s3 = list.stream().filter(s -&gt; s.startsWith(<span class="hljs-string">&quot;张&quot;</span>));<br><span class="hljs-comment">//         Object[] arrs = s3.toArray();</span><br>        String[] arrs = s3.toArray(String[]::<span class="hljs-keyword">new</span>); <span class="hljs-comment">// 可以不管，拓展一下思维！！</span><br>        System.out.println(<span class="hljs-string">&quot;Arrays数组内容：&quot;</span> + Arrays.toString(arrs));<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="异常处理">异常处理</h4>
<h6 id="什么是异常">什么是异常</h6>
<ul>
<li>异常是程序在“编译”或者“执行”的过程中可能出现的问题，注意：语法错误不算在异常体系中。</li>
<li>比如：数组索引越界、空指针异常、</li>
<li>日期格式化异常，等…</li>
</ul>
<h6 id="为什么要学习异常">为什么要学习异常？</h6>
<ul>
<li>异常一旦出现了，如果没有提前处理，程序就会退出JM虚拟机而终止</li>
<li>研究异常并且避免异常，然后提前处理异常，体现的是程序的安全，健壮性。</li>
</ul>
<h6 id="异常分为几类">异常分为几类？</h6>
<ul>
<li>编译时异常、运行时异常。</li>
<li>编译时异常：没有继承RuntimeExcpetion的异常，编译阶段就会错。</li>
<li>运行时异常：继承自RuntimeException的异常或其子类，编译阶段不报错，运行可能报错。</li>
</ul>
<h6 id="运行时异常示例">运行时异常示例</h6>
<ul>
<li>数组索引越界异常：ArraylndexOutOfBoundsException</li>
<li>空指针异常：NullPointerException,直接输出没有问题，但是调用空指针的变量的功能就会报错。</li>
<li>数学操作异常：ArithmeticException</li>
<li>类型转换异常：ClassCastException</li>
<li>数字转换异常：NumberFormatException</li>
</ul>
<h6 id="编译时异常"><strong>编译时异常</strong></h6>
<ul>
<li>不是RuntimeException或者其子类的异常，编译阶就报错，必须处理，否则代码不通过。</li>
<li>是担心程序员的技术不行，在编译阶段就爆出一个错误，目的在于提醒不要出错！</li>
<li>编译时异常是可遇不可求，遇到了就遇到了呗。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">String</span> <span class="hljs-variable">date</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;2015-01-12 10:23:21&quot;</span>;<br><span class="hljs-type">SimpleDateFormat</span> <span class="hljs-variable">sdf</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SimpleDateFormat</span>(<span class="hljs-string">&quot;yyyy-MM-dd HH:mm:ss&quot;</span>);<br><span class="hljs-type">Date</span> <span class="hljs-variable">d</span> <span class="hljs-operator">=</span> sdf.parse(date);<span class="hljs-comment">//</span><br>System.out.println(d);<br></code></pre></td></tr></table></figure>
<h6 id="异常处理-1">异常处理</h6>
<p><strong>异常处理方式1—— throws</strong></p>
<ul>
<li><p>throws：用在方法上，可以将方法内部出现的异常抛出去给本方法的调用者处理。</p></li>
<li><p>这种方式并不好，发生异常的方法自己不处理异常，如果异常最终抛出去给虚拟机将引起程序死亡。</p></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java">方法 <span class="hljs-keyword">throws</span> Exception&#123;<br>&#125;<br><span class="hljs-comment">//代表抛一切异常</span><br></code></pre></td></tr></table></figure>
<p><strong>异常处理方式2—— try…catch…</strong></p>
<ul>
<li><p>监视捕获异常，用在方法内部，可以将方法内部出现的异常直接捕获处理。</p></li>
<li><p>这种方式还可以，发生异常的方法自己独立完成异常的处理，程序可以继续往下执行。</p></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">try</span>&#123;<br>    <span class="hljs-comment">// 可能出现异常的代码！</span><br>&#125;<span class="hljs-keyword">catch</span> (Exception e)&#123;<br>    e.printStackTrace(); <br>    <span class="hljs-comment">// 直接打印异常栈信息</span><br>&#125;<br><span class="hljs-comment">//Exception可以捕获处理一切异常类型！</span><br></code></pre></td></tr></table></figure>
<p><strong>异常处理方式——前两者结合</strong></p>
<ul>
<li><p>方法直接将异通过throws抛出去给调用者</p></li>
<li><p>调用者收到异常后直接捕获处理。</p></li>
</ul>
<h6 id="自定义异常的必要"><strong>自定义异常的必要</strong>？</h6>
<ul>
<li><p>Java无法为这个世界上全部的问题提供异常类。</p></li>
<li><p>如果企业想通过异常的方式来管理自己的某个业务问题，就需要自定义异常类了。</p></li>
</ul>
<h6 id="自定义异常的好处"><strong>自定义异常的好处：</strong></h6>
<ul>
<li><p>可以使用异常的机制管理业务问题，如提醒程序员注意。</p></li>
<li><p>同时一旦出现bug，可以用异常的形式清晰的指出出错的地方。</p></li>
</ul>
<h6 id="自定义异常分类">自定义异常分类</h6>
<p><strong>1、自定义编译时异常</strong></p>
<ul>
<li><p>定义一个异常类继承Exception.</p></li>
<li><p>重写构造器。</p></li>
<li><p>在出现异常的地方用throw new 自定义对象抛出，</p></li>
</ul>
<p>作用：编译时异常是编译阶段就报错，提醒更加强烈，一定需要处理！！</p>
<p><strong>2、自定义运行时异常</strong></p>
<ul>
<li><p>定义一个异常类继承RuntimeException.</p></li>
<li><p>重写构造器。</p></li>
<li><p>在出现异常的地方用throw new 自定义对象抛出!</p></li>
</ul>
<p>作用：提醒不强烈，编译阶段不报错！！运行时才可能出现！！</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    自定义的编译时异常</span><br><span class="hljs-comment">      1、继承Exception</span><br><span class="hljs-comment">      2、重写构造器</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ItheimaAgeIlleagalException</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Exception</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ItheimaAgeIlleagalException</span><span class="hljs-params">()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ItheimaAgeIlleagalException</span><span class="hljs-params">(String message)</span> &#123;<br>        <span class="hljs-built_in">super</span>(message);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    自定义的运行时异常</span><br><span class="hljs-comment">      1、继承RuntimeException</span><br><span class="hljs-comment">      2、重写构造器</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ItheimaAgeIlleagalRuntimeException</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">RuntimeException</span>&#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ItheimaAgeIlleagalRuntimeException</span><span class="hljs-params">()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ItheimaAgeIlleagalRuntimeException</span><span class="hljs-params">(String message)</span> &#123;<br>        <span class="hljs-built_in">super</span>(message);<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标:自定义异常(了解)</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    引入:Java已经为开发中可能出现的异常都设计了一个类来代表.</span><br><span class="hljs-comment">        但是实际开发中,异常可能有无数种情况,Java无法为</span><br><span class="hljs-comment">        这个世界上所有的异常都定义一个代表类。</span><br><span class="hljs-comment">        假如一个企业如果想为自己认为的某种业务问题定义成一个异常</span><br><span class="hljs-comment">        就需要自己来自定义异常类.</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    需求：认为年龄小于0岁，大于200岁就是一个异常。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    自定义异常:</span><br><span class="hljs-comment">        自定义编译时异常.</span><br><span class="hljs-comment">            a.定义一个异常类继承Exception.</span><br><span class="hljs-comment">            b.重写构造器。</span><br><span class="hljs-comment">            c.在出现异常的地方用throw new 自定义对象抛出!</span><br><span class="hljs-comment">            编译时异常是编译阶段就报错，提醒更加强烈，一定需要处理！！</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">        自定义运行时异常.</span><br><span class="hljs-comment">            a.定义一个异常类继承RuntimeException.</span><br><span class="hljs-comment">            b.重写构造器。</span><br><span class="hljs-comment">            c.在出现异常的地方用throw new 自定义对象抛出!</span><br><span class="hljs-comment">            提醒不强烈，编译阶段不报错！！运行时才可能出现！！</span><br><span class="hljs-comment"></span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ExceptionDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br><span class="hljs-comment">//        try &#123;</span><br><span class="hljs-comment">//            checkAge(-34);</span><br><span class="hljs-comment">//        &#125; catch (ItheimaAgeIlleagalException e) &#123;</span><br><span class="hljs-comment">//            e.printStackTrace();</span><br><span class="hljs-comment">//        &#125;</span><br><br>        <span class="hljs-keyword">try</span> &#123;<br>            checkAge2(-<span class="hljs-number">23</span>);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">checkAge2</span><span class="hljs-params">(<span class="hljs-type">int</span> age)</span>  &#123;<br>        <span class="hljs-keyword">if</span>(age &lt; <span class="hljs-number">0</span> || age &gt; <span class="hljs-number">200</span>)&#123;<br>            <span class="hljs-comment">// 抛出去一个异常对象给调用者</span><br>            <span class="hljs-comment">// throw ：在方法内部直接创建一个异常对象，并从此点抛出</span><br>            <span class="hljs-comment">// throws : 用在方法申明上的，抛出方法内部的异常</span><br>            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ItheimaAgeIlleagalRuntimeException</span>(age + <span class="hljs-string">&quot; is illeagal!&quot;</span>);<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;年龄合法：推荐商品给其购买~~&quot;</span>);<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">checkAge</span><span class="hljs-params">(<span class="hljs-type">int</span> age)</span> <span class="hljs-keyword">throws</span> ItheimaAgeIlleagalException &#123;<br>        <span class="hljs-keyword">if</span>(age &lt; <span class="hljs-number">0</span> || age &gt; <span class="hljs-number">200</span>)&#123;<br>            <span class="hljs-comment">// 抛出去一个异常对象给调用者</span><br>            <span class="hljs-comment">// throw ：在方法内部直接创建一个异常对象，并从此点抛出</span><br>            <span class="hljs-comment">// throws : 用在方法申明上的，抛出方法内部的异常</span><br>            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ItheimaAgeIlleagalException</span>(age + <span class="hljs-string">&quot; is illeagal!&quot;</span>);<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;年龄合法：推荐商品给其购买~~&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="日志技术">日志技术</h4>
<h6 id="日志技术具备的优势">日志技术具备的优势</h6>
<ul>
<li>可以将系统执行的信息选择性的记录到指定的位置(控制台、文件中、数据库中)。</li>
<li>可以随时以开关的形式控制是否记录日志，无需修改源代码。</li>
</ul>
<table>
<colgroup>
<col style="width: 11%" />
<col style="width: 37%" />
<col style="width: 51%" />
</colgroup>
<thead>
<tr class="header">
<th></th>
<th><strong>输出语句</strong></th>
<th><strong>日志技术</strong></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>输出位置</td>
<td>只能是控制台</td>
<td>可以将日志信息写入到文件或者数据库中</td>
</tr>
<tr class="even">
<td>取消日志</td>
<td>需要修改代码，灵活性比较差</td>
<td>不需要修改代码，灵活性比较好</td>
</tr>
<tr class="odd">
<td>多线程</td>
<td>性能较差</td>
<td>性能较好</td>
</tr>
</tbody>
</table>
<h6
id="日志的规范是什么常见的有几种形式"><strong>1.日志的规范是什么，常见的有几种形式。</strong></h6>
<ul>
<li>日志规范大多是一些接口，提供给实现框架去设计的。</li>
<li>常见的规范是：</li>
<li>Commons Logging</li>
<li>Simple Logging Facade for Java</li>
</ul>
<h6
id="日志的实现框架有哪些常见的"><strong>2.日志的实现框架有哪些常见的？</strong></h6>
<ul>
<li>Log4</li>
<li>Logback(我们重点学习的，其他的都大同小异)</li>
</ul>
<h6
id="使用logback需要使用哪几个模块各自的作用是什么">3.使用Logback需要使用哪几个模块，各自的作用是什么。</h6>
<ul>
<li>slf4j-api:日志规范</li>
<li>logback-core:基础模块。</li>
<li>logback-classic:它是log4j的一个改良版本，同时它完整实现了slf4码API。</li>
</ul>
<h6
id="需求导入logback日志技术到项目中用于纪录系统的日志信息">需求：导入Logback日志技术到项目中，用于纪录系统的日志信息</h6>
<p>分析：</p>
<p>①：在项目下新建文件夹lib，导入Logback的相关jar包到该文件夹下，并添加到项目依赖库中去。</p>
<p><img src="JAVA基础/image-20220427193401207.png" srcset="/img/loading.gif" lazyload alt="image-20220427193401207" style="zoom:50%;" /></p>
<p>②：将Logback的核心配置文件logback.xml直接拷贝到src目录下（必须是src下）。</p>
<p>③：在代码中获取日志的对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">Logger</span> <span class="hljs-variable">LOGGER</span> <span class="hljs-operator">=</span> LoggerFactory.getLogger(<span class="hljs-string">&quot;类对象&quot;</span>);<br></code></pre></td></tr></table></figure>
<p>④：使用日志对象LOGGER调用其方法输出不能的日志信息</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> 快速搭建logback框架</span><br><span class="hljs-comment"> */</span><br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">logback</span> &#123;<br>    <span class="hljs-comment">//创建logback对象</span><br>  <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">Logger</span> <span class="hljs-variable">LOGGER</span> <span class="hljs-operator">=</span> LoggerFactory.getLogger(<span class="hljs-string">&quot;logback.class&quot;</span>);<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            LOGGER.debug(<span class="hljs-string">&quot;main方法开始执行&quot;</span>);<br>            LOGGER.info(<span class="hljs-string">&quot;第二行代码&quot;</span>);<br>            <span class="hljs-type">int</span> <span class="hljs-variable">a</span> <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;<br>            <span class="hljs-type">int</span> <span class="hljs-variable">b</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;<br>            LOGGER.trace(<span class="hljs-string">&quot;a=&quot;</span>+a);<br>            LOGGER.trace(<span class="hljs-string">&quot;b=&quot;</span>+b);<br>            System.out.println(a / b);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>            LOGGER.error(<span class="hljs-string">&quot;功能出现异常&quot;</span>+e);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="日志级别">日志级别</h6>
<ul>
<li><p>级别程度依次是：TRACE&lt; DEBUG&lt; INFO&lt;WARN&lt;ERROR ;
默认级别是debug（忽略大小写），对应其方法。</p></li>
<li><p>作用：用于控制系统中哪些日志级别是可以输出的，只输出级别不低于设定级别的日志信息。</p></li>
<li><p>ALL 和 OFF分别是打开全部日志信息，及关闭全部日志信息。</p></li>
</ul>
<p>具体在<code>&lt;root level="INFO"&gt;</code>标签的level属性中设置日志级别。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">root</span> <span class="hljs-attr">level</span>=<span class="hljs-string">“INFO</span>&quot;&gt;</span><br>	<span class="hljs-tag">&lt;<span class="hljs-name">appender-ref</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;CONSOLE&quot;</span>/&gt;</span><br>	<span class="hljs-tag">&lt;<span class="hljs-name">appender-ref</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&quot;FILE&quot;</span> /&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">root</span>&gt;</span><br></code></pre></td></tr></table></figure>
<h4 id="文件">文件</h4>
<h6 id="file类概述">File类概述</h6>
<p>File类在包java.io.File下、代表操作系统的文件对象(文件、文件夹)。
File类提供了诸如：定位文件，获取文件本身的信息、删除文件、创建文件（文件夹）等功能。</p>
<h6 id="创建file对象">创建File对象</h6>
<table>
<colgroup>
<col style="width: 47%" />
<col style="width: 52%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>public</strong> File(String pathname)</td>
<td>根据文件路径创建文件对象</td>
</tr>
<tr class="even">
<td><strong>public</strong> File(String parent, String child)</td>
<td>从父路径名字符串和子路径名字符串创建文件对象</td>
</tr>
<tr class="odd">
<td><strong>public</strong> File(File parent, String child)</td>
<td>根据父路径对应文件对象和子路径名字符串创建文件对象</td>
</tr>
</tbody>
</table>
<p>绝对路径：从盘符开始</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">File</span> <span class="hljs-variable">file1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">File</span>(“D:\\itheima\\a.txt”); <br></code></pre></td></tr></table></figure>
<p>相对路径：不带盘符，默认直接到当前工程下的目录寻找文件。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">File</span> <span class="hljs-variable">file3</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">File</span>(“模块名\\a.txt”); <br></code></pre></td></tr></table></figure>
<h6
id="file类的判断文件类型获取文件信息功能">File类的判断文件类型、获取文件信息功能</h6>
<table>
<colgroup>
<col style="width: 43%" />
<col style="width: 56%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public boolean isDirectory()</td>
<td>测试此抽象路径名表示的File是否为文件夹</td>
</tr>
<tr class="even">
<td>public boolean isFile()</td>
<td>测试此抽象路径名表示的File是否为文件</td>
</tr>
<tr class="odd">
<td>public boolean exists()</td>
<td>测试此抽象路径名表示的File是否存在</td>
</tr>
<tr class="even">
<td>public String getAbsolutePath()</td>
<td>返回此抽象路径名的绝对路径名字符串</td>
</tr>
<tr class="odd">
<td>public String getPath()</td>
<td>将此抽象路径名转换为路径名字符串</td>
</tr>
<tr class="even">
<td>public String getName()</td>
<td>返回由此抽象路径名表示的文件或文件夹的名称</td>
</tr>
<tr class="odd">
<td>public long lastModified()</td>
<td>返回文件最后修改的时间毫秒值</td>
</tr>
</tbody>
</table>
<h6 id="file类创建文件的功能">File类创建文件的功能</h6>
<table>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public boolean createNewFile()</td>
<td>创建一个新的空的文件</td>
</tr>
<tr class="even">
<td>public boolean mkdir()</td>
<td>只能创建一级文件夹</td>
</tr>
<tr class="odd">
<td>public boolean mkdirs()</td>
<td>可以创建多级文件夹</td>
</tr>
</tbody>
</table>
<h6 id="file类删除文件的功能">File类删除文件的功能</h6>
<table>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public boolean delete()</td>
<td>删除由此抽象路径名表示的文件或空文件夹</td>
</tr>
</tbody>
</table>
<ul>
<li><p>delete方法默认只能删除文件和空文件夹。</p></li>
<li><p>delete方法直接删除不走回收站</p></li>
</ul>
<h6 id="file类的遍历功能"><strong>File</strong>类的遍历功能</h6>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public String[] list()</td>
<td>获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。</td>
</tr>
<tr class="even">
<td>public File[] listFiles()(常用)</td>
<td>获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回（重点）</td>
</tr>
</tbody>
</table>
<p><strong>listFiles方法注意事项：</strong></p>
<ul>
<li>当调用者不存在时，返回null</li>
<li>当调用者是一个文件时，返回null</li>
<li>当调用者是一个空文件夹时，返回一个长度为0的数组</li>
<li>当调用者是一个有内容的文件夹时，将里面所有文件和文件夹的路径放在File数组中返回</li>
<li>当调用者是一个有隐藏文件的文件夹时，将里面所有文件和文件夹的路径放在File数组中返回，包含隐藏内容</li>
<li>当调用者是一个需要权限才能进入的文件夹时，返回null</li>
</ul>
<h6 id="递归">递归</h6>
<p><strong>递归算法三要素大体可以总结为</strong>：</p>
<ul>
<li>递归的公式：f（）=f(n-1)*n;</li>
<li>递归的终结点：f(1)</li>
<li>递归的方向必须走向终结点：</li>
</ul>
<p><strong>需求：计算1-n的阶乘的结果，使用递归思想解决，我们先从数学思维上理解递归的流程和核心点。</strong></p>
<p>分析</p>
<p>①假如我们认为存在一个公式是 f(n) = 1**2<em>…(n-1)</em>n;</p>
<p>②那么公式等价形式就是： f(n) = f(n-1) *n</p>
<p>③如果求的是 1-5的阶乘
的结果，我们手工应该应该如何应用上述公式计算。</p>
<ul>
<li>f(5) = f(4) * 5</li>
<li>f(4) = f(3) * 4</li>
<li>f(3) = f(2) * 3</li>
<li>f(2) = f(1) * 2</li>
<li>f(1) = 1</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RecursionDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        System.out.println(f(<span class="hljs-number">5</span>));<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> <span class="hljs-title function_">f</span><span class="hljs-params">(<span class="hljs-type">int</span> n)</span>&#123;<br>        <span class="hljs-keyword">if</span>(n == <span class="hljs-number">1</span>)&#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-keyword">return</span> f(n - <span class="hljs-number">1</span>) * n;<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>案例</strong></p>
<p>猴子第一天摘下若干桃子，当即吃了一半，觉得好不过瘾，于是又多吃了一个</p>
<p>第二天又吃了前天剩余桃子数量的一半，觉得好不过瘾，于是又多吃了一个</p>
<p>以后每天都是吃前天剩余桃子数量的一半，觉得好不过瘾，又多吃了一个</p>
<p>等到第10天的时候发现桃子只有1个了。</p>
<p>需求：请问猴子第一天摘了多少个桃子？</p>
<p>分析：</p>
<p>①整体来看，每一天都是做同一个事件，典型的规律化问题，考虑递归三要素：</p>
<p>②递归公式：</p>
<p>③递归终结点：</p>
<p>④递归方向：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">      目标 猴子吃桃。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     公式（合理的）： f(x) - f(x)/2 - 1 = f(x+1)</span><br><span class="hljs-comment">                   2f(x) - f(x) - 2 = 2f(x + 1)</span><br><span class="hljs-comment">                   f(x) = 2f(x + 1) + 2</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    求f(1) = ?</span><br><span class="hljs-comment">    终结点： f（10） = 1</span><br><span class="hljs-comment">    递归的方向：合理的</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RecursionDemo04</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        System.out.println(f(<span class="hljs-number">1</span>));<br>        System.out.println(f(<span class="hljs-number">2</span>));<br>        System.out.println(f(<span class="hljs-number">3</span>));<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> <span class="hljs-title function_">f</span><span class="hljs-params">(<span class="hljs-type">int</span> n)</span>&#123;<br>        <span class="hljs-keyword">if</span>(n == <span class="hljs-number">10</span>)&#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-number">2</span> * f(n + <span class="hljs-number">1</span>) + <span class="hljs-number">2</span>;<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：去D判断搜索 eDiary.exe文件</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">RecursionDemo05</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 2、传入目录 和  文件名称</span><br>        searchFile(<span class="hljs-keyword">new</span> <span class="hljs-title class_">File</span>(<span class="hljs-string">&quot;D:/&quot;</span>) , <span class="hljs-string">&quot;eDiary.exe&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 1、搜索某个目录下的全部文件，找到我们想要的文件。</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> dir  被搜索的源目录</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> fileName 被搜索的文件名称</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">searchFile</span><span class="hljs-params">(File dir,String fileName)</span>&#123;<br>        <span class="hljs-comment">// 3、判断dir是否是目录</span><br>        <span class="hljs-keyword">if</span>(dir != <span class="hljs-literal">null</span> &amp;&amp; dir.isDirectory())&#123;<br>            <span class="hljs-comment">// 可以找了</span><br>            <span class="hljs-comment">// 4、提取当前目录下的一级文件对象</span><br>            File[] files = dir.listFiles(); <span class="hljs-comment">// null  []</span><br>            <span class="hljs-comment">// 5、判断是否存在一级文件对象，存在才可以遍历</span><br>            <span class="hljs-keyword">if</span>(files != <span class="hljs-literal">null</span> &amp;&amp; files.length &gt; <span class="hljs-number">0</span>) &#123;<br>                <span class="hljs-keyword">for</span> (File file : files) &#123;<br>                    <span class="hljs-comment">// 6、判断当前遍历的一级文件对象是文件 还是 目录</span><br>                    <span class="hljs-keyword">if</span>(file.isFile())&#123;<br>                        <span class="hljs-comment">// 7、是不是咱们要找的，是把其路径输出即可</span><br>                        <span class="hljs-keyword">if</span>(file.getName().contains(fileName))&#123;<br>                            System.out.println(<span class="hljs-string">&quot;找到了：&quot;</span> + file.getAbsolutePath());<br>                            <span class="hljs-comment">// 启动它。</span><br>                            <span class="hljs-keyword">try</span> &#123;<br>                                <span class="hljs-type">Runtime</span> <span class="hljs-variable">r</span> <span class="hljs-operator">=</span> Runtime.getRuntime();<br>                                r.exec(file.getAbsolutePath());<br>                            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>                                e.printStackTrace();<br>                            &#125;<br>                        &#125;<br>                    &#125;<span class="hljs-keyword">else</span> &#123;<br>                        <span class="hljs-comment">// 8、是文件夹，需要继续递归寻找</span><br>                        searchFile(file, fileName);<br>                    &#125;<br>                &#125;<br>            &#125;<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;对不起，当前搜索的位置不是文件夹！&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="字符集">字符集</h4>
<h6
id="字符串常见的字符底层组成是什么样的">1.字符串常见的字符底层组成是什么样的？</h6>
<ul>
<li>英文和数字等在任何国家的字符集中都占1个字节</li>
<li>GBK字符中一个中文字符占2个字节</li>
<li>UTF-8编码中一个中文1般占3个字节</li>
</ul>
<h6
id="编码前的字符集和编码好的字符集有什么要求">2.编码前的字符集和编码好的字符集有什么要求？</h6>
<ul>
<li>必须一致，否则会出现中文字符乱码</li>
</ul>
<p>String编码</p>
<table>
<colgroup>
<col style="width: 36%" />
<col style="width: 63%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>byte[] getBytes()</td>
<td>使用平台的默认字符集将该
String编码为一系列字节，将结果存储到新的字节数组中</td>
</tr>
<tr class="even">
<td>byte[] getBytes(String charsetName)</td>
<td>使用指定的字符集将该
String编码为一系列字节，将结果存储到新的字节数组中</td>
</tr>
</tbody>
</table>
<p>String解码</p>
<table>
<colgroup>
<col style="width: 40%" />
<col style="width: 60%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>String(byte[] bytes)</td>
<td>通过使用平台的默认字符集解码指定的字节数组来构造新的 String</td>
</tr>
<tr class="even">
<td>String(byte[] bytes, String charsetName)</td>
<td>通过指定的字符集解码指定的字节数组来构造新的 String</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：学会自己进行文字的编码和解码，为以后可能用到的场景做准备。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Test</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、编码：把文字转换成字节（使用指定的编码）</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;abc我爱你中国&quot;</span>;<br>        <span class="hljs-comment">// byte[] bytes = name.getBytes(); // 以当前代码默认字符集进行编码 （UTF-8）</span><br>        <span class="hljs-type">byte</span>[] bytes = name.getBytes(<span class="hljs-string">&quot;GBK&quot;</span>); <span class="hljs-comment">// 指定编码</span><br>        System.out.println(bytes.length);<br>        System.out.println(Arrays.toString(bytes));<br><br>        <span class="hljs-comment">// 2、解码：把字节转换成对应的中文形式（编码前 和 编码后的字符集必须一致，否则乱码 ）</span><br>        <span class="hljs-comment">// String rs = new String(bytes); // 默认的UTF-8</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(bytes, <span class="hljs-string">&quot;GBK&quot;</span>); <span class="hljs-comment">// 指定GBK解码</span><br>        System.out.println(rs);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="io流">IO流</h4>
<h6 id="io流概述"><strong>IO</strong>流概述</h6>
<ul>
<li><p>I表示intput，是数据从硬盘文件读入到内存的过程，称之输入，负责读。</p></li>
<li><p>O表示output，是内存程序的数据从内存到写出到硬盘文件的过程，称之输出，负责写。</p></li>
</ul>
<h6 id="总结流的四大类"><strong>总结</strong>流的四大类:</h6>
<ul>
<li><p>字节输入流：以内存为基准，来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流。</p></li>
<li><p>字节输出流：以内存为基准，把内存中的数据以字节写出到磁盘文件或者网络中去的流称为字节输出流。</p></li>
<li><p>字符输入流：以内存为基准，来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流。</p></li>
<li><p>字符输出流：以内存为基准，把内存中的数据以字符写出到磁盘文件或者网络介质中去的流称为字符输出流。</p></li>
</ul>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220428190902198.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="fileinputstream">FileInputStream</h6>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public int read()</td>
<td>每次读取一个字节返回，如果字节已经没有可读的返回-1</td>
</tr>
<tr class="even">
<td>public int read(byte[] buffer)</td>
<td>每次读取一个字节数组返回读取字节数，如果字节已经没有可读的返回-1</td>
</tr>
</tbody>
</table>
<p>1.如何使用字节输入流读取中文内容输出不乱码呢？ 一次性读取完全部字节。
可以定义与文件一样大的字节数组读取，也可以使用官方API。
2.直接把文件数据全部读取到一个字节数组可以避免乱码，是否存在问题？
如果文件过大，定义的字节数组可能引起内存溢出。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：使用文件字节输入流每次读取一个字节数组的数据。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FileInputStreamDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建一个文件字节输入流管道与源文件接通</span><br>        <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(<span class="hljs-string">&quot;file-io-app/src/data02.txt&quot;</span>);<br><br>        <span class="hljs-comment">// 2、定义一个字节数组，用于读取字节数组</span><br><span class="hljs-comment">//        byte[] buffer = new byte[3]; // 3B</span><br><span class="hljs-comment">//        int len = is.read(buffer);</span><br><span class="hljs-comment">//        System.out.println(&quot;读取了几个字节：&quot; + len);</span><br><span class="hljs-comment">//        String rs = new String(buffer);</span><br><span class="hljs-comment">//        System.out.println(rs);</span><br><span class="hljs-comment">//</span><br><span class="hljs-comment">//        int len1 = is.read(buffer);</span><br><span class="hljs-comment">//        System.out.println(&quot;读取了几个字节：&quot; + len1);</span><br><span class="hljs-comment">//        String rs1 = new String(buffer);</span><br><span class="hljs-comment">//        System.out.println(rs1);</span><br><span class="hljs-comment">//        // buffer = [a b c]</span><br><span class="hljs-comment">//</span><br><span class="hljs-comment">//        // buffer = [a b c]  ==&gt;  [c d c]</span><br><span class="hljs-comment">//        int len2 = is.read(buffer);</span><br><span class="hljs-comment">//        System.out.println(&quot;读取了几个字节：&quot; + len2);</span><br><span class="hljs-comment">//        // 读取多少倒出多少</span><br><span class="hljs-comment">//        String rs2 = new String(buffer,0 ,len2);</span><br><span class="hljs-comment">//        System.out.println(rs2);</span><br><span class="hljs-comment">//</span><br><span class="hljs-comment">//        int len3 = is.read(buffer);</span><br><span class="hljs-comment">//        System.out.println(len3); // 读取完毕返回-1</span><br><br>        <span class="hljs-comment">// 3、改进使用循环，每次读取一个字节数组</span><br>        <span class="hljs-type">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">3</span>];<br>        <span class="hljs-type">int</span> len; <span class="hljs-comment">// 记录每次读取的字节数。</span><br>        <span class="hljs-keyword">while</span> ((len = is.read(buffer)) != -<span class="hljs-number">1</span>) &#123;<br>            <span class="hljs-comment">// 读取多少倒出多少</span><br>            System.out.print(<span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(buffer, <span class="hljs-number">0</span> , len));<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="文件字节输出流fileoutputstream"><strong>文件字节输出流：FileOutputStream</strong></h6>
<p>作用：以内存为基准，把内存中的数据以字节的形式写出到磁盘文件中去的流。</p>
<table>
<colgroup>
<col style="width: 54%" />
<col style="width: 45%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public FileOutputStream(File file)</td>
<td>创建字节输出流管道与源文件对象接通</td>
</tr>
<tr class="even">
<td>public FileOutputStream(File file，boolean append)</td>
<td>创建字节输出流管道与源文件对象接通，可追加数据</td>
</tr>
<tr class="odd">
<td>public FileOutputStream(String filepath)</td>
<td>创建字节输出流管道与源文件路径接通</td>
</tr>
<tr class="even">
<td>public FileOutputStream(String filepath，boolean append)</td>
<td>创建字节输出流管道与源文件路径接通，可追加数据</td>
</tr>
</tbody>
</table>
<h6
id="文件字节输出流fileoutputstream写数据出去的api">文件字节输出流（FileOutputStream）写数据出去的API</h6>
<table>
<colgroup>
<col style="width: 65%" />
<col style="width: 35%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void write(int a)</td>
<td>写一个字节出去</td>
</tr>
<tr class="even">
<td>public void write(byte[] buffer)</td>
<td>写一个字节数组出去</td>
</tr>
<tr class="odd">
<td>public void write(byte[] buffer , int pos , int len)</td>
<td>写一个字节数组的一部分出去。</td>
</tr>
</tbody>
</table>
<h6 id="流的关闭与刷新"><strong>流的关闭与刷新</strong></h6>
<table>
<colgroup>
<col style="width: 10%" />
<col style="width: 89%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>flush()</td>
<td>刷新流，还可以继续写数据</td>
</tr>
<tr class="even">
<td>close()</td>
<td>关闭流，释放资源，但是在关闭之前会先刷新流。一旦关闭，就不能再写数据</td>
</tr>
</tbody>
</table>
<p>字节输出流如何实现写出去的数据能换行?</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs java">os.write“\r\n”.getBytes())<br></code></pre></td></tr></table></figure>
<p>如何让写出去的数据能成功生效？</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java">flush()刷新数据<br><br>close()方法是关闭流，关闭包含刷新，关闭后流不可以继续使用了。<br></code></pre></td></tr></table></figure>
<h6 id="案例文件复制">案例：文件复制</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> *   目标：学会使用finally释放资源。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TryCatchFinallyDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br>        <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br>        <span class="hljs-keyword">try</span> &#123;<br><br>            <span class="hljs-comment">// System.out.println(10/ 0);</span><br><br>            <span class="hljs-comment">// 1、创建一个字节输入流管道与原视频接通</span><br>             is = <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(<span class="hljs-string">&quot;file-io-app/src/out04.txt&quot;</span>);<br><br>            <span class="hljs-comment">// 2、创建一个字节输出流管道与目标文件接通</span><br>             os = <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">&quot;file-io-app/src/out05.txt&quot;</span>);<br><br>            <span class="hljs-comment">// 3、定义一个字节数组转移数据</span><br>            <span class="hljs-type">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">1024</span>];<br>            <span class="hljs-type">int</span> len; <span class="hljs-comment">// 记录每次读取的字节数。</span><br>            <span class="hljs-keyword">while</span> ((len = is.read(buffer)) != -<span class="hljs-number">1</span>)&#123;<br>                os.write(buffer, <span class="hljs-number">0</span> , len);<br>            &#125;<br>            System.out.println(<span class="hljs-string">&quot;复制完成了！&quot;</span>);<br><br>         <span class="hljs-comment">//   System.out.println( 10 / 0);</span><br><br>        &#125; <span class="hljs-keyword">catch</span> (Exception e)&#123;<br>            e.printStackTrace();<br>        &#125; <span class="hljs-keyword">finally</span> &#123;<br>            <span class="hljs-comment">// 无论代码是正常结束，还是出现异常都要最后执行这里</span><br>            System.out.println(<span class="hljs-string">&quot;========finally=========&quot;</span>);<br>            <span class="hljs-keyword">try</span> &#123;<br>                <span class="hljs-comment">// 4、关闭流。</span><br>                <span class="hljs-keyword">if</span>(os!=<span class="hljs-literal">null</span>)os.close();<br>            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>                e.printStackTrace();<br>            &#125;<br>            <span class="hljs-keyword">try</span> &#123;<br>                <span class="hljs-keyword">if</span>(is != <span class="hljs-literal">null</span>) is.close();<br>            &#125; <span class="hljs-keyword">catch</span> (IOException e) &#123;<br>                e.printStackTrace();<br>            &#125;<br>        &#125;<br><br>        System.out.println(test(<span class="hljs-number">10</span>, <span class="hljs-number">2</span>));<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> <span class="hljs-title function_">test</span><span class="hljs-params">(<span class="hljs-type">int</span> a , <span class="hljs-type">int</span> b)</span>&#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-type">int</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> a / b;<br>            <span class="hljs-keyword">return</span> c;<br>        &#125;<span class="hljs-keyword">catch</span> (Exception e)&#123;<br>            e.printStackTrace();<br>            <span class="hljs-keyword">return</span> -<span class="hljs-number">111111</span>; <span class="hljs-comment">// 计算出现bug.</span><br>        &#125;<span class="hljs-keyword">finally</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;--finally--&quot;</span>);<br>            <span class="hljs-comment">// 哪怕上面有return语句执行，也必须先执行完这里才可以！</span><br>            <span class="hljs-comment">// 开发中不建议在这里加return ，如果加了，返回的永远是这里的数据了，这样会出问题！</span><br>            <span class="hljs-comment">//return 100;</span><br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> *   目标：学会使用JDK 7的新方式释放资源</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TryCatchResouceDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br><br>        <span class="hljs-keyword">try</span> (<br>                <span class="hljs-comment">// 这里面只能放置资源对象，用完会自动关闭：自动调用资源对象的close方法关闭资源（即使出现异常也会做关闭操作）</span><br>                <span class="hljs-comment">// 1、创建一个字节输入流管道与原视频接通</span><br>               <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(<span class="hljs-string">&quot;file-io-app/src/out04.txt&quot;</span>);<br>                <span class="hljs-comment">// 2、创建一个字节输出流管道与目标文件接通</span><br>               <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">&quot;file-io-app/src/out05.txt&quot;</span>);<br><br>               <span class="hljs-comment">// int age = 23; // 这里只能放资源</span><br>                <span class="hljs-type">MyConnection</span> <span class="hljs-variable">connection</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyConnection</span>(); <span class="hljs-comment">// 最终会自动调用资源的close方法</span><br>                ) &#123;<br><br>            <span class="hljs-comment">// 3、定义一个字节数组转移数据</span><br>            <span class="hljs-type">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">1024</span>];<br>            <span class="hljs-type">int</span> len; <span class="hljs-comment">// 记录每次读取的字节数。</span><br>            <span class="hljs-keyword">while</span> ((len = is.read(buffer)) != -<span class="hljs-number">1</span>)&#123;<br>                os.write(buffer, <span class="hljs-number">0</span> , len);<br>            &#125;<br>            System.out.println(<span class="hljs-string">&quot;复制完成了！&quot;</span>);<br><br>        &#125; <span class="hljs-keyword">catch</span> (Exception e)&#123;<br>            e.printStackTrace();<br>        &#125;<br><br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MyConnection</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">AutoCloseable</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">close</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> IOException &#123;<br>        System.out.println(<span class="hljs-string">&quot;连接资源被成功释放了！&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="字节流适合做一切文件数据的拷贝吗">1.字节流适合做一切文件数据的拷贝吗？</h6>
<ul>
<li>任何文件的底层都是字节，拷贝是一字不漏的转移字节，只要前后文件格式、编码一致没有任何问题。</li>
</ul>
<h6 id="文件字符输入流">文件字符输入流</h6>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 49%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public FileReader(File file)</td>
<td>创建字符输入流管道与源文件对象接通</td>
</tr>
<tr class="even">
<td>public FileReader(String pathname)</td>
<td>创建字符输入流管道与源文件路径接通</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public int read()</td>
<td>每次读取一个字符返回，如果字符已经没有可读的返回-1</td>
</tr>
<tr class="even">
<td>public int read(char[] buffer)</td>
<td>每次读取一个字符数组，返回读取的字符个数，如果字符已经没有可读的返回-1</td>
</tr>
</tbody>
</table>
<p>字符流的好处，每次读取一个字符存在什么问题？
读取中文字符不会出现乱码（如果代码和文件编码一致） 性能较慢</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：字符输入流的使用。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     IO流的体系：</span><br><span class="hljs-comment">            字节流                                   字符流</span><br><span class="hljs-comment">     字节输入流           字节输出流               字符输入流       字符输出流</span><br><span class="hljs-comment">     InputStream         OutputStream            Reader         Writer     (抽象类)</span><br><span class="hljs-comment">     FileInputStream     FileOutputStream        FileReader     FileWriter (实现类)</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     c.FileReader:文件字符输入流。</span><br><span class="hljs-comment">         -- 作用：以内存为基准，把磁盘文件的数据以字符的形式读入到内存。</span><br><span class="hljs-comment">            简单来说，读取文本文件内容到内存中去。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">         -- 构造器：</span><br><span class="hljs-comment">            public FileReader(File file):创建一个字符输入流与源文件对象接通。</span><br><span class="hljs-comment">            public FileReader(String filePath):创建一个字符输入流与源文件路径接通。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">         -- 方法：</span><br><span class="hljs-comment">            public int read(): 读取一个字符的编号返回！ 读取完毕返回-1</span><br><span class="hljs-comment">            public int read(char[] buffer):读取一个字符数组，读取多少个字符就返回多少个数量，读取完毕返回-1</span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">        字符流一个一个字符的读取文本内容输出，可以解决中文读取输出乱码的问题。</span><br><span class="hljs-comment">        字符流很适合操作文本文件内容。</span><br><span class="hljs-comment">        但是：一个一个字符的读取文本内容性能较差！！</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FileReaderDemo01</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 目标：每次读取一个字符。</span><br>        <span class="hljs-comment">// 1、创建一个字符输入流管道与源文件接通</span><br>        <span class="hljs-type">Reader</span> <span class="hljs-variable">fr</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileReader</span>(<span class="hljs-string">&quot;file-io-app\\src\\data06.txt&quot;</span>);<br><br>        <span class="hljs-comment">// 2、读取一个字符返回，没有可读的字符了返回-1</span><br><span class="hljs-comment">//        int code = fr.read();</span><br><span class="hljs-comment">//        System.out.print((char)code);</span><br><span class="hljs-comment">//</span><br><span class="hljs-comment">//        int code1 = fr.read();</span><br><span class="hljs-comment">//        System.out.print((char)code1);</span><br><br>        <span class="hljs-comment">// 3、使用循环读取字符</span><br>        <span class="hljs-type">int</span> code;<br>        <span class="hljs-keyword">while</span> ((code = fr.read()) != -<span class="hljs-number">1</span>)&#123;<br>            System.out.print((<span class="hljs-type">char</span>) code);<br>        &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FileReaderDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建一个文件字符输入流与源文件接通</span><br>        <span class="hljs-type">Reader</span> <span class="hljs-variable">fr</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileReader</span>(<span class="hljs-string">&quot;file-io-app/src/data07.txt&quot;</span>);<br><br>        <span class="hljs-comment">// 2、用循环，每次读取一个字符数组的数据。  1024 + 1024 + 8</span><br>        <span class="hljs-type">char</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">char</span>[<span class="hljs-number">1024</span>]; <span class="hljs-comment">// 1K字符</span><br>        <span class="hljs-type">int</span> len;<br>        <span class="hljs-keyword">while</span> ((len = fr.read(buffer)) != -<span class="hljs-number">1</span>) &#123;<br>            <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(buffer, <span class="hljs-number">0</span>, len);<br>            System.out.print(rs);<br>        &#125;<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：字符输出流的使用。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     IO流的体系：</span><br><span class="hljs-comment">            字节流                                   字符流</span><br><span class="hljs-comment">     字节输入流           字节输出流               字符输入流       字符输出流</span><br><span class="hljs-comment">     InputStream         OutputStream           Reader         Writer     (抽象类)</span><br><span class="hljs-comment">     FileInputStream     FileOutputStream       FileReader     FileWriter (实现类)</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     d.FileWriter文件字符输出流的使用。</span><br><span class="hljs-comment">        -- 作用：以内存为基准，把内存中的数据按照字符的形式写出到磁盘文件中去。</span><br><span class="hljs-comment">            简单来说，就是把内存的数据以字符写出到文件中去。</span><br><span class="hljs-comment">        -- 构造器：</span><br><span class="hljs-comment">           public FileWriter(File file):创建一个字符输出流管道通向目标文件对象。</span><br><span class="hljs-comment">           public FileWriter(String filePath):创建一个字符输出流管道通向目标文件路径。</span><br><span class="hljs-comment">           public FileWriter(File file,boolean append):创建一个追加数据的字符输出流管道通向目标文件对象。</span><br><span class="hljs-comment">           public FileWriter(String filePath,boolean append):创建一个追加数据的字符输出流管道通向目标文件路径。</span><br><span class="hljs-comment">        -- 方法：</span><br><span class="hljs-comment">             a.public void write(int c):写一个字符出去</span><br><span class="hljs-comment">             b.public void write(String c)写一个字符串出去：</span><br><span class="hljs-comment">             c.public void write(char[] buffer):写一个字符数组出去</span><br><span class="hljs-comment">             d.public void write(String c ,int pos ,int len):写字符串的一部分出去</span><br><span class="hljs-comment">             e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去</span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">        字符输出流可以写字符数据出去，总共有5个方法写字符。</span><br><span class="hljs-comment">        覆盖管道：</span><br><span class="hljs-comment">             Writer fw = new FileWriter(&quot;Day10Demo/src/dlei03.txt&quot;); // 覆盖数据管道</span><br><span class="hljs-comment">        追加数据管道：</span><br><span class="hljs-comment">             Writer fw = new FileWriter(&quot;Day10Demo/src/dlei03.txt&quot;,true); // 追加数据管道</span><br><span class="hljs-comment">        换行：</span><br><span class="hljs-comment">             fw.write(&quot;\r\n&quot;); // 换行</span><br><span class="hljs-comment">        结论：读写字符文件数据建议使用字符流。复制文件建议使用字节流。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FileWriterDemo03</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建一个字符输出流管道与目标文件接通</span><br>        <span class="hljs-comment">// Writer fw = new FileWriter(&quot;file-io-app/src/out08.txt&quot;); // 覆盖管道，每次启动都会清空文件之前的数据</span><br>        <span class="hljs-type">Writer</span> <span class="hljs-variable">fw</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileWriter</span>(<span class="hljs-string">&quot;file-io-app/src/out08.txt&quot;</span>, <span class="hljs-literal">true</span>); <span class="hljs-comment">// 覆盖管道，每次启动都会清空文件之前的数据</span><br><br><span class="hljs-comment">//      a.public void write(int c):写一个字符出去</span><br>        fw.write(<span class="hljs-number">98</span>);<br>        fw.write(<span class="hljs-string">&#x27;a&#x27;</span>);<br>        fw.write(<span class="hljs-string">&#x27;徐&#x27;</span>); <span class="hljs-comment">// 不会出问题了</span><br>        fw.write(<span class="hljs-string">&quot;\r\n&quot;</span>); <span class="hljs-comment">// 换行</span><br><br><span class="hljs-comment">//       b.public void write(String c)写一个字符串出去</span><br>        fw.write(<span class="hljs-string">&quot;abc我是中国人&quot;</span>);<br>        fw.write(<span class="hljs-string">&quot;\r\n&quot;</span>); <span class="hljs-comment">// 换行</span><br><br><br><span class="hljs-comment">//       c.public void write(char[] buffer):写一个字符数组出去</span><br>        <span class="hljs-type">char</span>[] chars = <span class="hljs-string">&quot;abc我是中国人&quot;</span>.toCharArray();<br>        fw.write(chars);<br>        fw.write(<span class="hljs-string">&quot;\r\n&quot;</span>); <span class="hljs-comment">// 换行</span><br><br><br><span class="hljs-comment">//       d.public void write(String c ,int pos ,int len):写字符串的一部分出去</span><br>        fw.write(<span class="hljs-string">&quot;abc我是中国人&quot;</span>, <span class="hljs-number">0</span>, <span class="hljs-number">5</span>);<br>        fw.write(<span class="hljs-string">&quot;\r\n&quot;</span>); <span class="hljs-comment">// 换行</span><br><br><br><span class="hljs-comment">//       e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去</span><br>        fw.write(chars, <span class="hljs-number">3</span>, <span class="hljs-number">5</span>);<br>        fw.write(<span class="hljs-string">&quot;\r\n&quot;</span>); <span class="hljs-comment">// 换行</span><br><br><br>        <span class="hljs-comment">// fw.flush();// 刷新后流可以继续使用</span><br>        fw.close(); <span class="hljs-comment">// 关闭包含刷线，关闭后流不能使用</span><br><br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<h4 id="缓冲流">缓冲流</h4>
<h6 id="缓冲流概述">缓冲流概述</h6>
<p>缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
作用：缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429095931746.png" srcset="/img/loading.gif" lazyload class="">
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429100034115.png" srcset="/img/loading.gif" lazyload class="">
<p>1.缓冲流的作用？
缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能
2.缓冲流有几种？ 字节缓冲流 字节缓冲输入流：BufferedInputStream
字节缓冲输出流：BufferedOutputStream 字符缓冲流
字符缓冲输入流：BufferedReader 字符缓冲输出流：BufferedWriter</p>
<p><strong>字节缓冲流性能优化原理：</strong></p>
<p>​
字节缓冲输入流自带了8KB缓冲池，以后我们直接从缓冲池读取数据，所以性能较好。</p>
<p>​
字节缓冲输出流自带了8KB缓冲池，数据就直接写入到缓冲池中去，写数据性能极高了。</p>
<table>
<colgroup>
<col style="width: 42%" />
<col style="width: 57%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public BufferedInputStream(InputStream is)</td>
<td>可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道，从而提高字节输入流读数据的性能</td>
</tr>
<tr class="even">
<td>public BufferedOutputStream(OutputStream os)</td>
<td>可以把低级的字节输出流包装成一个高级的缓冲字节输出流，从而提高写数据的性能</td>
</tr>
</tbody>
</table>
<p>1.推荐使用哪种方式提高字节流读写数据的性能？</p>
<p><strong>建议使用字节缓冲输入流、字节缓冲输出流，结合字节数组的方式，目前来看是性能最优的组合。</strong></p>
<h6 id="字符缓冲输入流"><strong>字符缓冲输入流</strong></h6>
<p>字符缓冲输入流：BufferedReader。</p>
<p>作用：提高字符输入流读取数据的性能，除此之外多了按照行读取数据的功能</p>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public BufferedReader(Reader r)</td>
<td>可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道，从而提高字符输入流读数据的性能</td>
</tr>
</tbody>
</table>
<h6
id="字符缓冲输入流新增功能"><strong>字符缓冲输入流新增功能</strong></h6>
<table>
<colgroup>
<col style="width: 32%" />
<col style="width: 67%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public String readLine()</td>
<td>读取一行数据返回，如果读取没有完毕，无行可读返回null</td>
</tr>
</tbody>
</table>
<h6 id="字符缓冲输出流"><strong>字符缓冲输出流</strong></h6>
<p>字符缓冲输出流：BufferedWriter。</p>
<p>作用：提高字符输出流写取数据的性能，除此之外多了换行功能</p>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public BufferedWriter(Writer w)</td>
<td>可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道，从而提高字符输出流写数据的性能</td>
</tr>
</tbody>
</table>
<h6
id="字符缓冲输出流新增功能"><strong>字符缓冲输出流新增功能</strong></h6>
<table>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void newLine()</td>
<td>换行操作</td>
</tr>
</tbody>
</table>
<h4 id="转换流">转换流</h4>
<p>1、如果代码编码和文件编码不一致，使用字符流直接读取还能不乱码吗？
会乱码。 2、如果如何解决呢？ 使用字符输入转换流
可以提取文件(GBK)的原始字节流，原始字节不会存在问题。
然后把字节流以指定编码转换成字符输入流，这样字符输入流中的字符就不乱码了</p>
<table>
<colgroup>
<col style="width: 48%" />
<col style="width: 51%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public InputStreamReader(InputStream is)</td>
<td>可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用，与默认的FileReader一样。</td>
</tr>
<tr class="even">
<td>public InputStreamReader(InputStream is ，String charset)</td>
<td>可以把原始的字节流按照指定编码转换成字符输入流，这样字符流中的字符就不乱码了(重点)</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：字符输入转换流InputStreamReader的使用。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">             字节流                                     字符流</span><br><span class="hljs-comment">     字节输入流               字节输出流              字符输入流            字符输出流</span><br><span class="hljs-comment">     InputStream             OutputStream          Reader               Writer   (抽象类)</span><br><span class="hljs-comment">     FileInputStream         FileOutputStream      FileReader           FileWriter(实现类)</span><br><span class="hljs-comment">     BufferedInputStream     BufferedOutputStream  BufferedReader       BufferedWriter(实现类，缓冲流)</span><br><span class="hljs-comment">                                                   InputStreamReader    OutputStreamWriter</span><br><span class="hljs-comment">     字符输入转换流InputStreamReader:</span><br><span class="hljs-comment">          -- 作用：可以解决字符流读取不同编码乱码的问题。</span><br><span class="hljs-comment">                  也可以把原始的字节流按照指定编码转换成字符输入流</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">          -- 构造器：</span><br><span class="hljs-comment">                public InputStreamReader(InputStream is)：可以使用当前代码默认编码转换成字符流，几乎不用！</span><br><span class="hljs-comment">                public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">        字符输入转换流InputStreamReader:作用：可以解决字符流读取不同编码乱码的问题。</span><br><span class="hljs-comment">        public InputStreamReader(InputStream is,String charset):可以指定编码把字节流转换成字符流(核心)</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InputStreamReaderDemo01</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 代码UTF-8   文件 GBK  &quot;D:\\resources\\data.txt&quot;</span><br>        <span class="hljs-comment">// 1、提取GBK文件的原始字节流。   abc 我</span><br>        <span class="hljs-comment">//                            ooo oo</span><br>        <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(<span class="hljs-string">&quot;D:\\resources\\data.txt&quot;</span>);<br>        <span class="hljs-comment">// 2、把原始字节流转换成字符输入流</span><br>        <span class="hljs-comment">// Reader isr = new InputStreamReader(is); // 默认以UTF-8的方式转换成字符流。 还是会乱码的  跟直接使用FileReader是一样的</span><br>        <span class="hljs-type">Reader</span> <span class="hljs-variable">isr</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InputStreamReader</span>(is , <span class="hljs-string">&quot;GBK&quot;</span>); <span class="hljs-comment">// 以指定的GBK编码转换成字符输入流  完美的解决了乱码问题</span><br><br>        <span class="hljs-type">BufferedReader</span> <span class="hljs-variable">br</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedReader</span>(isr);<br>        String line;<br>        <span class="hljs-keyword">while</span> ((line = br.readLine()) != <span class="hljs-literal">null</span>)&#123;<br>            System.out.println(line);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>字符输出转换流</strong></p>
<p>字符输入转换流：OutputStreamWriter，可以把字节输出流按照指定编码转换成字符输出流。</p>
<table>
<colgroup>
<col style="width: 49%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public OutputStreamWriter(OutputStream os)</td>
<td>可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用。</td>
</tr>
<tr class="even">
<td>public OutputStreamWriter(OutputStream os，String charset)</td>
<td>可以把原始的字节输出流按照指定编码转换成字符输出流(重点)</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：字符输出转换OutputStreamWriter流的使用。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">                字节流                                         字符流</span><br><span class="hljs-comment">     字节输入流               字节输出流              字符输入流            字符输出流</span><br><span class="hljs-comment">     InputStream             OutputStream          Reader               Writer   (抽象类)</span><br><span class="hljs-comment">     FileInputStream         FileOutputStream      FileReader           FileWriter(实现类)</span><br><span class="hljs-comment">     BufferedInputStream     BufferedOutputStream  BufferedReader       BufferedWriter(实现类，缓冲流)</span><br><span class="hljs-comment">                                                   InputStreamReader    OutputStreamWriter</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     字符输出转换流：OutputStreamWriter</span><br><span class="hljs-comment">           -- 作用：可以指定编码把字节输出流转换成字符输出流。</span><br><span class="hljs-comment">                   可以指定写出去的字符的编码。</span><br><span class="hljs-comment">           -- 构造器：</span><br><span class="hljs-comment">                public OutputStreamWriter(OutputStream os) :   用当前默认编码UTF-8把字节输出流转换成字符输出流</span><br><span class="hljs-comment">                public OutputStreamWriter(OutputStream os , String charset):指定编码把字节输出流转换成字符输出流</span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">        字符输出转换流OutputStreamWriter可以指定编码把字节输出流转换成字符输出流。</span><br><span class="hljs-comment">        从而实现指定写出去的字符编码！</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">OutputStreamWriterDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、定义一个字节输出流</span><br>        <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">&quot;io-app2/src/out03.txt&quot;</span>);<br><br>        <span class="hljs-comment">// 2、把原始的字节输出流转换成字符输出流</span><br>        <span class="hljs-comment">// Writer osw = new OutputStreamWriter(os); // 以默认的UTF-8写字符出去 跟直接写FileWriter一样</span><br>        <span class="hljs-type">Writer</span> <span class="hljs-variable">osw</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">OutputStreamWriter</span>(os , <span class="hljs-string">&quot;GBK&quot;</span>); <span class="hljs-comment">// 指定GBK的方式写字符出去</span><br><br>        <span class="hljs-comment">// 3、把低级的字符输出流包装成高级的缓冲字符输出流。</span><br>        <span class="hljs-type">BufferedWriter</span> <span class="hljs-variable">bw</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedWriter</span>(osw);<br><br>        bw.write(<span class="hljs-string">&quot;我爱中国1~~&quot;</span>);<br>        bw.write(<span class="hljs-string">&quot;我爱中国2~~&quot;</span>);<br>        bw.write(<span class="hljs-string">&quot;我爱中国3~~&quot;</span>);<br><br>        bw.close();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="对象序列化">对象序列化</h4>
<h6 id="对象序列化-1"><strong>对象序列化</strong>：</h6>
<p>作用：以内存为基准，把内存中的对象存储到磁盘文件中去，称为对象序列化。</p>
<p>使用到的流是对象字节输出流：ObjectOutputStream</p>
<table>
<colgroup>
<col style="width: 51%" />
<col style="width: 48%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public ObjectOutputStream(OutputStream out)</td>
<td>把低级字节输出流包装成高级的对象字节输出流</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 53%" />
<col style="width: 46%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public final void writeObject(Object obj)</td>
<td>把对象写出去到对象序列化流的文件中去</td>
</tr>
</tbody>
</table>
<p>1.对象序列化的含义是什么？</p>
<p><strong>把对象数据存入到文件中去。</strong></p>
<p>2.对象序列化用到了哪个流？</p>
<p><strong>对象字节输出流ObjectOutputStram</strong></p>
<p><strong>public void writeObject(Object obj)</strong></p>
<p>3.序列化对象的要求是怎么样的？</p>
<p><strong>对象必须实现序列化接口</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  对象如果要序列化，必须实现Serializable序列化接口。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Serializable</span> &#123;<br>    <span class="hljs-comment">// 申明序列化的版本号码</span><br>    <span class="hljs-comment">// 序列化的版本号与反序列化的版本号必须一致才不会出错！</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">long</span> <span class="hljs-variable">serialVersionUID</span> <span class="hljs-operator">=</span> <span class="hljs-number">1</span>;<br>    <span class="hljs-keyword">private</span> String name;<br>    <span class="hljs-keyword">private</span> String loginName;<br>    <span class="hljs-comment">// transient修饰的成员变量不参与序列化了</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">transient</span> String passWord;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> age ;<br>	.<br>    .<br>    .  <br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：学会对象序列化，使用 ObjectOutputStream 把内存中的对象存入到磁盘文件中。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     transient修饰的成员变量不参与序列化了</span><br><span class="hljs-comment">     对象如果要序列化，必须实现Serializable序列化接口。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     申明序列化的版本号码</span><br><span class="hljs-comment">     序列化的版本号与反序列化的版本号必须一致才不会出错！</span><br><span class="hljs-comment">     private static final long serialVersionUID = 1;</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ObjectOutputStreamDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建学生对象</span><br>        <span class="hljs-type">Student</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>(<span class="hljs-string">&quot;陈磊&quot;</span>, <span class="hljs-string">&quot;chenlei&quot;</span>,<span class="hljs-string">&quot;1314520&quot;</span>, <span class="hljs-number">21</span>);<br><br>        <span class="hljs-comment">// 2、对象序列化：使用对象字节输出流包装字节输出流管道</span><br>        <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">oos</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">&quot;io-app2/src/obj.txt&quot;</span>));<br><br>        <span class="hljs-comment">// 3、直接调用序列化方法</span><br>        oos.writeObject(s);<br><br>        <span class="hljs-comment">// 4、释放资源</span><br>        oos.close();<br>        System.out.println(<span class="hljs-string">&quot;序列化完成了~~&quot;</span>);<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="对象反序列化"><strong>对象反序列化</strong>：</h6>
<p>使用到的流是对象字节输入流：ObjectInputStream</p>
<p>作用：以内存为基准，把存储到磁盘文件中去的对象数据恢复成内存中的对象，称为对象反序列化。</p>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public ObjectInputStream(InputStream out)</td>
<td>把低级字节输如流包装成高级的对象字节输入流</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 34%" />
<col style="width: 65%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public Object readObject()</td>
<td>把存储到磁盘文件中去的对象数据恢复成内存中的对象返回</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：学会进行对象反序列化：使用对象字节输入流把文件中的对象数据恢复成内存中的Java对象。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ObjectInputStreamDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建对象字节输入流管道包装低级的字节输入流管道</span><br>        <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(<span class="hljs-string">&quot;io-app2/src/obj.txt&quot;</span>));<br><br>        <span class="hljs-comment">// 2、调用对象字节输入流的反序列化方法</span><br>        <span class="hljs-type">Student</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> (Student) is.readObject();<br><br>        System.out.println(s);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="打印流">打印流</h6>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429103304035.png" srcset="/img/loading.gif" lazyload class="">
<p><strong>打印流</strong></p>
<p>作用：打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指：PrintStream，PrintWriter两个类。</p>
<p>可以实现打印什么数据就是什么数据，例如打印整数97写出去就是97，打印boolean的true，写出去就是true。</p>
<p><strong>PrintStream</strong></p>
<table>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public PrintStream(OutputStream os)</td>
<td>打印流直接通向字节输出流管道</td>
</tr>
<tr class="even">
<td>public PrintStream(File f)</td>
<td>打印流直接通向文件对象</td>
</tr>
<tr class="odd">
<td>public PrintStream(String filepath)</td>
<td>打印流直接通向文件路径</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void print(Xxx xx)</td>
<td>打印任意类型的数据出去</td>
</tr>
</tbody>
</table>
<p><strong>PrintWriter</strong></p>
<table>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public PrintWriter(OutputStream os)</td>
<td>打印流直接通向字节输出流管道</td>
</tr>
<tr class="even">
<td>public PrintWriter (Writer w)</td>
<td>打印流直接通向字符输出流管道</td>
</tr>
<tr class="odd">
<td>public PrintWriter (File f)</td>
<td>打印流直接通向文件对象</td>
</tr>
<tr class="even">
<td>public PrintWriter (String filepath)</td>
<td>打印流直接通向文件路径</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void print(Xxx xx)</td>
<td>打印任意类型的数据出去</td>
</tr>
</tbody>
</table>
<p><strong>PrintStream和PrintWriter的区别</strong></p>
<p>打印数据功能上是一模一样的，都是使用方便，性能高效（核心优势）</p>
<p>PrintStream继承自字节输出流OutputStream，支持写字节数据的方法。</p>
<p>PrintWriter继承自字符输出流Writer，支持写字符数据出去。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：学会使用打印流 高效  方便写数据到文件。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PrintDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建一个打印流对象</span><br><span class="hljs-comment">//        PrintStream ps = new PrintStream(new FileOutputStream(&quot;io-app2/src/ps.txt&quot;));</span><br><span class="hljs-comment">//        PrintStream ps = new PrintStream(new FileOutputStream(&quot;io-app2/src/ps.txt&quot; , true)); // 追加数据，在低级管道后面加True</span><br><span class="hljs-comment">//        PrintStream ps = new PrintStream(&quot;io-app2/src/ps.txt&quot; );</span><br>        <span class="hljs-type">PrintWriter</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintWriter</span>(<span class="hljs-string">&quot;io-app2/src/ps.txt&quot;</span>); <span class="hljs-comment">// 打印功能上与PrintStream的使用没有区别</span><br><br>        ps.println(<span class="hljs-number">97</span>);<br>        ps.println(<span class="hljs-string">&#x27;a&#x27;</span>);<br>        ps.println(<span class="hljs-number">23.3</span>);<br>        ps.println(<span class="hljs-literal">true</span>);<br>        ps.println(<span class="hljs-string">&quot;我是打印流输出的，我是啥就打印啥&quot;</span>);<br><br>        ps.close();<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：了解改变输出语句的位置到文件</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PrintDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        System.out.println(<span class="hljs-string">&quot;锦瑟无端五十弦&quot;</span>);<br>        System.out.println(<span class="hljs-string">&quot;一弦一柱思华年&quot;</span>);<br><br>        <span class="hljs-comment">// 改变输出语句的位置（重定向）</span><br>        <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(<span class="hljs-string">&quot;io-app2/src/log.txt&quot;</span>);<br>        System.setOut(ps); <span class="hljs-comment">// 把系统打印流改成我们自己的打印流</span><br><br>        System.out.println(<span class="hljs-string">&quot;庄生晓梦迷蝴蝶&quot;</span>);<br>        System.out.println(<span class="hljs-string">&quot;望帝春心托杜鹃&quot;</span>);<br>    &#125;<br>&#125;<br><br></code></pre></td></tr></table></figure>
<p>1.打印流有几种？各有什么特点？</p>
<p><strong>打印流一般是指：PrintStream，PrintWriter两个类。</strong></p>
<p><strong>打印功能2者是一样的使用方式</strong></p>
<p><strong>PrintStream继承自字节输出流OutputStream，支持写字节</strong></p>
<p><strong>PrintWrite继承自字符输出流Writer，支持写字符</strong></p>
<p>2.打印流的优势是什么？</p>
<p><strong>两者在打印功能上都是使用方便，性能高效（核心优势）</strong></p>
<h6 id="补充知识properties">补充知识Properties</h6>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429104602782.png" srcset="/img/loading.gif" lazyload class="">
<p><strong>Properties属性集对象</strong></p>
<p>​
其实就是一个Map集合，但是我们一般不会当集合使用，因为HashMap更好用。</p>
<p><strong>Properties核心作用：</strong></p>
<p>​
Properties代表的是一个属性文件，可以把自己对象中的键值对信息存入到一个属性文件中去。</p>
<p>​ 属性文件：后缀是.properties结尾的文件,里面的内容都是
key=value，后续做系统配置信息的。</p>
<p>1.Properties的作用？</p>
<p><strong>可以存储Properties属性集的键值对数据到属性文件中去：</strong></p>
<p>​ <strong>void store(Writer writer, String comments)</strong></p>
<p><strong>可以加载属性文件中的数据到Properties对象中来：</strong></p>
<p>​ <strong>void load(Reader reader)</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Properties的概述和使用(框架底层使用，了解这个技术即可)（保存数据到属性文件）</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Properties: 属性集对象。</span><br><span class="hljs-comment">         其实就是一个Map集合。也就是一个键值对集合，但是我们一般不会当集合使用，</span><br><span class="hljs-comment">         因为有HashMap。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Properties核心作用：</span><br><span class="hljs-comment">         Properties代表的是一个属性文件，可以把键值对的数据存入到一个属性文件中去。</span><br><span class="hljs-comment">         属性文件：后缀是.properties结尾的文件,里面的内容都是 key=value。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    大家在后期学的很多大型框架技术中，属性文件都是很重要的系统配置文件。</span><br><span class="hljs-comment">        users.properties</span><br><span class="hljs-comment">                admin=123456</span><br><span class="hljs-comment">                dlei=dlei</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     需求：使用Properties对象生成一个属性文件，里面存入用户名和密码信息。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     Properties的方法：</span><br><span class="hljs-comment">         -- public Object setProperty(String key, String value) ： 保存一对属性。  (put)</span><br><span class="hljs-comment">         -- public String getProperty(String key) : 使用此属性列表中指定的键搜索属性值 (get)</span><br><span class="hljs-comment">         -- public Set&lt;String&gt; stringPropertyNames() : 所有键的名称的集合  (keySet())</span><br><span class="hljs-comment">         -- public void store(OutputStream out, String comments): 保存数据到属性文件中去</span><br><span class="hljs-comment">         -- public void store(Writer fw, String comments): 保存数据到属性文件中去</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">            Properties可以保存键值对数据到属性文件</span><br><span class="hljs-comment"></span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PropertiesDemo01</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 需求：使用Properties把键值对信息存入到属性文件中去。</span><br>        <span class="hljs-type">Properties</span> <span class="hljs-variable">properties</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Properties</span>();<br>        properties.setProperty(<span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;123456&quot;</span>);<br>        properties.setProperty(<span class="hljs-string">&quot;dlei&quot;</span>, <span class="hljs-string">&quot;003197&quot;</span>);<br>        properties.setProperty(<span class="hljs-string">&quot;heima&quot;</span>, <span class="hljs-string">&quot;itcast&quot;</span>);<br>        System.out.println(properties);<br><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">           参数一：保存管道 字符输出流管道</span><br><span class="hljs-comment">           参数二：保存心得</span><br><span class="hljs-comment">         */</span><br>        properties.store(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileWriter</span>(<span class="hljs-string">&quot;io-app2/src/users.properties&quot;</span>)<br>                , <span class="hljs-string">&quot;this is users!! i am very happy! give me 100!&quot;</span>);<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Properties读取属性文件中的键值对信息。（读取）</span><br><span class="hljs-comment">    Properties的方法：</span><br><span class="hljs-comment">        -- public Object setProperty(String key, String value) ： 保存一对属性。</span><br><span class="hljs-comment">        -- public String getProperty(String key) ：使用此属性列表中指定的键搜索属性值</span><br><span class="hljs-comment">        -- public Set&lt;String&gt; stringPropertyNames() ：所有键的名称的集合</span><br><span class="hljs-comment">        -- public void store(OutputStream out, String comments):保存数据到属性文件中去</span><br><span class="hljs-comment">        -- public synchronized void load(InputStream inStream):加载属性文件的数据到属性集对象中去</span><br><span class="hljs-comment">        -- public synchronized void load(Reader fr):加载属性文件的数据到属性集对象中去</span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">        属性集对象可以加载读取属性文件中的数据!!</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PropertiesDemo02</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 需求：Properties读取属性文件中的键值对信息。（读取）</span><br>        <span class="hljs-type">Properties</span> <span class="hljs-variable">properties</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Properties</span>();<br>        System.out.println(properties);<br><br>        <span class="hljs-comment">// 加载属性文件中的键值对数据到属性对象properties中去</span><br>        properties.load(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileReader</span>(<span class="hljs-string">&quot;io-app2/src/users.properties&quot;</span>));<br><br>        System.out.println(properties);<br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> properties.getProperty(<span class="hljs-string">&quot;dlei&quot;</span>);<br>        System.out.println(rs);<br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs1</span> <span class="hljs-operator">=</span> properties.getProperty(<span class="hljs-string">&quot;admin&quot;</span>);<br>        System.out.println(rs1);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<table>
<colgroup>
<col style="width: 46%" />
<col style="width: 53%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>void load(InputStream inStream)</td>
<td>从输入字节流读取属性列表（键和元素对）</td>
</tr>
<tr class="even">
<td>void load(Reader reader)</td>
<td>从输入字符流读取属性列表（键和元素对）</td>
</tr>
<tr class="odd">
<td>void store(OutputStream out, String comments)</td>
<td>将此属性列表（键和元素对）写入此 Properties表中，以适合于使用
load(InputStream)方法的格式写入输出字节流</td>
</tr>
<tr class="even">
<td>void store(Writer writer, String comments)</td>
<td>将此属性列表（键和元素对）写入此 Properties表中，以适合使用
load(Reader)方法的格式写入输出字符流</td>
</tr>
<tr class="odd">
<td>public Object setProperty(String key, String value)</td>
<td>保存键值对（put）</td>
</tr>
<tr class="even">
<td>public String getProperty(String key)</td>
<td>使用此属性列表中指定的键搜索属性值 (get)</td>
</tr>
<tr class="odd">
<td>public Set<String> stringPropertyNames()</td>
<td>所有键的名称的集合 (keySet())</td>
</tr>
</tbody>
</table>
<h4 id="io框架commons-io">IO框架：commons-io</h4>
<p><strong>commons-io概述</strong></p>
<ul>
<li><p>commons-io是apache开源基金组织提供的一组有关IO操作的类库，可以提高IO功能开发的效率。</p></li>
<li><p>commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils,
IOUtils</p></li>
</ul>
<table>
<colgroup>
<col style="width: 67%" />
<col style="width: 32%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>String readFileToString(File file, String encoding)</td>
<td>读取文件中的数据, 返回字符串</td>
</tr>
<tr class="even">
<td>void copyFile(File srcFile, File destFile)</td>
<td>复制文件。</td>
</tr>
<tr class="odd">
<td>void copyDirectoryToDirectory(File srcDir, File destDir)</td>
<td>复制文件夹。</td>
</tr>
</tbody>
</table>
<p>导入commons-io-2.6.jar做开发</p>
<p><strong>需求</strong></p>
<p>使用commons-io简化io流读写</p>
<p><strong>分析</strong></p>
<p>①在项目中创建一个文件夹：lib</p>
<p>②将commons-io-2.6.jar文件复制到lib文件夹</p>
<p>③在jar文件上点右键，选择 Add as Library -&gt; 点击OK</p>
<p>④在类中导包使用</p>
<h2 id="线程">线程</h2>
<h4 id="线程创建方式">线程创建方式</h4>
<h6 id="thread类"><strong>Thread类</strong></h6>
<p>Java是通过java.lang.Thread 类来代表线程的。</p>
<p>按照面向对象的思想，Thread类应该提供了实现多线程的方式。</p>
<h6
id="多线程的实现方案一继承thread类"><strong>多线程的实现方案一：继承Thread类</strong></h6>
<p>①定义一个子类MyThread继承线程类java.lang.Thread，重写run()方法</p>
<p>②创建MyThread类的对象</p>
<p>③调用线程对象的start()方法启动线程（启动后还是执行run方法的）</p>
<p><strong>1.为什么不直接调用了run方法，而是调用start启动线程?</strong></p>
<ul>
<li><p>直接调用run方法会当成普通方法执行，此时相当于还是单线程执行。</p></li>
<li><p>只有调用start方法才是启动一个新的线程执行。</p></li>
</ul>
<p><strong>2、把主线程任务放在子线程之前了。</strong></p>
<ul>
<li>这样主线程一直是先跑完的，相当于是一个单线程的效果了。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：多线程的创建方式一：继承Thread类实现。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ThreadDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 3、new一个新线程对象</span><br>        <span class="hljs-type">Thread</span> <span class="hljs-variable">t</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyThread</span>();<br>        <span class="hljs-comment">// 4、调用start方法启动线程（执行的还是run方法）</span><br>        t.start();<br><br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) &#123;<br>            System.out.println(<span class="hljs-string">&quot;主线程执行输出：&quot;</span> + i);<br>        &#125;<br><br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">   1、定义一个线程类继承Thread类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MyThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span>&#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       2、重写run方法，里面是定义线程以后要干啥</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) &#123;<br>            System.out.println(<span class="hljs-string">&quot;子线程执行输出：&quot;</span> + i);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>方式一优缺点：</strong></p>
<p>优点：编码简单</p>
<p>缺点：线程类已经继承Thread，无法继承其他类，不利于扩展。</p>
<h6
id="多线程的实现方案二实现runnable口"><strong>多线程的实现方案二：实现Runnable口</strong></h6>
<p>①定义一个线程任务类MyRunnable实现Runnable接口，重写run()方法</p>
<p>②创建MyRunnable任务对象</p>
<p>③把MyRunnable任务对象交给Thread处理。</p>
<p>④调用线程对象的start()方法启动线程</p>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 49%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public Thread(String name)</td>
<td>可以为当前线程指定名称</td>
</tr>
<tr class="even">
<td>public Thread(Runnable target)</td>
<td>封装Runnable对象成为线程对象</td>
</tr>
<tr class="odd">
<td>public Thread(Runnable target ，String name )</td>
<td>封装Runnable对象成为线程对象，并指定线程名称</td>
</tr>
</tbody>
</table>
<p><strong>方式二优缺点：</strong></p>
<p>优点：线程任务类只是实现接口，可以继续继承类和实现接口，扩展性强。</p>
<p>缺点：编程多一层对象包装，如果线程有执行结果是不可以直接返回的</p>
<h6
id="多线程的实现方案三利用callablefuturetask接口实现"><strong>多线程的实现方案三：利用Callable、FutureTask接口实现。</strong></h6>
<p>①、得到任务对象</p>
<p>​ 1.定义类实现Callable接口，重写call方法，封装要做的事情。</p>
<p>​ 2.用FutureTask把Callable对象封装成线程任务对象。</p>
<p>②、把线程任务对象交给Thread处理。</p>
<p>③、调用Thread的start方法启动线程，执行任务</p>
<p>④、线程执行完毕后、通过FutureTask的get方法去获取任务执行的结果。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：学会线程的创建方式三：实现Callable接口，结合FutureTask完成。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ThreadDemo3</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 3、创建Callable任务对象</span><br>        Callable&lt;String&gt; call = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">100</span>);<br>        <span class="hljs-comment">// 4、把Callable任务对象 交给 FutureTask 对象</span><br>        <span class="hljs-comment">//  FutureTask对象的作用1： 是Runnable的对象（实现了Runnable接口），可以交给Thread了</span><br>        <span class="hljs-comment">//  FutureTask对象的作用2： 可以在线程执行完毕之后通过调用其get方法得到线程执行完成的结果</span><br>        FutureTask&lt;String&gt; f1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">FutureTask</span>&lt;&gt;(call);<br>        <span class="hljs-comment">// 5、交给线程处理</span><br>        <span class="hljs-type">Thread</span> <span class="hljs-variable">t1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Thread</span>(f1);<br>        <span class="hljs-comment">// 6、启动线程</span><br>        t1.start();<br><br><br>        Callable&lt;String&gt; call2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">200</span>);<br>        FutureTask&lt;String&gt; f2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">FutureTask</span>&lt;&gt;(call2);<br>        <span class="hljs-type">Thread</span> <span class="hljs-variable">t2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Thread</span>(f2);<br>        t2.start();<br><br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 如果f1任务没有执行完毕，这里的代码会等待，直到线程1跑完才提取结果。</span><br>            <span class="hljs-type">String</span> <span class="hljs-variable">rs1</span> <span class="hljs-operator">=</span> f1.get();<br>            System.out.println(<span class="hljs-string">&quot;第一个结果：&quot;</span> + rs1);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br><br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 如果f2任务没有执行完毕，这里的代码会等待，直到线程2跑完才提取结果。</span><br>            <span class="hljs-type">String</span> <span class="hljs-variable">rs2</span> <span class="hljs-operator">=</span> f2.get();<br>            System.out.println(<span class="hljs-string">&quot;第二个结果：&quot;</span> + rs2);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    1、定义一个任务类 实现Callable接口  应该申明线程任务执行完毕后的结果的数据类型</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">MyCallable</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Callable</span>&lt;String&gt;&#123;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> n;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">MyCallable</span><span class="hljs-params">(<span class="hljs-type">int</span> n)</span> &#123;<br>        <span class="hljs-built_in">this</span>.n = n;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       2、重写call方法（任务方法）</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">call</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-type">int</span> <span class="hljs-variable">sum</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">1</span>; i &lt;= n ; i++) &#123;<br>            sum += i;<br>        &#125;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;子线程执行的结果是：&quot;</span> + sum;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<table>
<colgroup>
<col style="width: 48%" />
<col style="width: 51%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public FutureTask&lt;&gt;(Callable call)</td>
<td>把Callable对象封装成FutureTask对象。</td>
</tr>
<tr class="even">
<td>public V get() throws Exception</td>
<td>获取线程执行call方法返回的结果。</td>
</tr>
</tbody>
</table>
<p><strong>方式三优缺点：</strong></p>
<p>优点：线程任务类只是实现接口，可以继续继承类和实现接口，扩展性强。</p>
<p>可以在线程执行完毕后去获取线程执行的结果。</p>
<p>缺点：编码复杂一点。</p>
<h6 id="三种方法对比">三种方法对比</h6>
<table>
<colgroup>
<col style="width: 12%" />
<col style="width: 46%" />
<col style="width: 41%" />
</colgroup>
<thead>
<tr class="header">
<th>方式</th>
<th>优点</th>
<th>缺点</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>继承Thread类</td>
<td>编程比较简单，可以直接使用Thread类中的方法</td>
<td>扩展性较差，不能再继承其他的类，不能返回线程执行的结果</td>
</tr>
<tr class="even">
<td>实现Runnable接口</td>
<td>扩展性强，实现该接口的同时还可以继承其他的类。</td>
<td>编程相对复杂，不能返回线程执行的结果</td>
</tr>
<tr class="odd">
<td>实现Callable接口</td>
<td>扩展性强，实现该接口的同时还可以继承其他的类。可以得到线程执行的结果</td>
<td>编程相对复杂</td>
</tr>
</tbody>
</table>
<h6 id="线程常用api">线程常用API</h6>
<table>
<colgroup>
<col style="width: 46%" />
<col style="width: 53%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>String getName()</td>
<td>获取当前线程的名称，默认线程名称是Thread-索引</td>
</tr>
<tr class="even">
<td>void setName(String name)</td>
<td>设置线程名称</td>
</tr>
<tr class="odd">
<td>public static Thread currentThread()：</td>
<td>返回对当前正在执行的线程对象的引用</td>
</tr>
<tr class="even">
<td>public static void sleep(long time)</td>
<td>让线程休眠指定的时间，单位为毫秒。</td>
</tr>
<tr class="odd">
<td>public void run()</td>
<td>线程任务方法</td>
</tr>
<tr class="even">
<td>public void start()</td>
<td>线程启动方法</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 52%" />
<col style="width: 47%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public Thread(String name)</td>
<td>可以为当前线程指定名称</td>
</tr>
<tr class="even">
<td>public Thread(Runnable target)</td>
<td>把Runnable对象交给线程对象</td>
</tr>
<tr class="odd">
<td>public Thread(Runnable target ，String name )</td>
<td>把Runnable对象交给线程对象，并指定线程名称</td>
</tr>
</tbody>
</table>
<h6 id="线程安全问题"><strong>线程安全问题</strong></h6>
<p>多个线程同时操作同一个共享资源的时候可能会出现业务安全问题，称为线程安全问题。</p>
<p>1.线程安全问题出现的原因？</p>
<p><strong>存在多线程并发</strong></p>
<p><strong>同时访问共享资源</strong></p>
<p><strong>存在修改共享资源</strong></p>
<h6 id="案例家庭账户问题">案例：家庭账户问题</h6>
<p>小明和小红是一对夫妻，他们有一个共同的账户，余额是10万元，模拟2人同时去取钱10万。</p>
<p><strong>分析：</strong></p>
<p>①：需要提供一个账户类，创建一个账户对象代表2个人的共享账户。</p>
<p>②：需要定义一个线程类，线程类可以处理账户对象。</p>
<p>③：创建2个线程对象，传入同一个账户对象。</p>
<p>④：启动2个线程，去同一个账户对象中取钱10万。</p>
<p>//银行亏十万</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Account</span> &#123;<br>    <span class="hljs-keyword">private</span> String cardId;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">double</span> money; <span class="hljs-comment">// 账户的余额</span><br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Account</span><span class="hljs-params">()</span>&#123;<br><br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Account</span><span class="hljs-params">(String cardId, <span class="hljs-type">double</span> money)</span> &#123;<br>        <span class="hljs-built_in">this</span>.cardId = cardId;<br>        <span class="hljs-built_in">this</span>.money = money;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       小明 小红</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">drawMoney</span><span class="hljs-params">(<span class="hljs-type">double</span> money)</span> &#123;<br>        <span class="hljs-comment">// 0、先获取是谁来取钱，线程的名字就是人名</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> Thread.currentThread().getName();<br>        <span class="hljs-comment">// 1、判断账户是否够钱</span><br>        <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.money &gt;= money)&#123;<br>            <span class="hljs-comment">// 2、取钱</span><br>            System.out.println(name + <span class="hljs-string">&quot;来取钱成功，吐出：&quot;</span> + money);<br>            <span class="hljs-comment">// 3、更新余额</span><br>            <span class="hljs-built_in">this</span>.money -= money;<br>            System.out.println(name + <span class="hljs-string">&quot;取钱后剩余：&quot;</span> + <span class="hljs-built_in">this</span>.money);<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-comment">// 4、余额不足</span><br>            System.out.println(name +<span class="hljs-string">&quot;来取钱，余额不足！&quot;</span>);<br>        &#125;<br><br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getCardId</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> cardId;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setCardId</span><span class="hljs-params">(String cardId)</span> &#123;<br>        <span class="hljs-built_in">this</span>.cardId = cardId;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">double</span> <span class="hljs-title function_">getMoney</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> money;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setMoney</span><span class="hljs-params">(<span class="hljs-type">double</span> money)</span> &#123;<br>        <span class="hljs-built_in">this</span>.money = money;<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   取钱的线程类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">DrawThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span> &#123;<br>    <span class="hljs-comment">// 接收处理的账户对象</span><br>    <span class="hljs-keyword">private</span> Account acc;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">DrawThread</span><span class="hljs-params">(Account acc,String name)</span>&#123;<br>        <span class="hljs-built_in">super</span>(name);<br>        <span class="hljs-built_in">this</span>.acc = acc;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 小明 小红：取钱</span><br>        acc.drawMoney(<span class="hljs-number">100000</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    需求：模拟取钱案例。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ThreadDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、定义线程类，创建一个共享的账户对象</span><br>        <span class="hljs-type">Account</span> <span class="hljs-variable">acc</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Account</span>(<span class="hljs-string">&quot;ICBC-111&quot;</span>, <span class="hljs-number">100000</span>);<br><br>        <span class="hljs-comment">// 2、创建2个线程对象，代表小明和小红同时进来了。</span><br>        <span class="hljs-keyword">new</span> <span class="hljs-title class_">DrawThread</span>(acc, <span class="hljs-string">&quot;小明&quot;</span>).start();<br>        <span class="hljs-keyword">new</span> <span class="hljs-title class_">DrawThread</span>(acc, <span class="hljs-string">&quot;小红&quot;</span>).start();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="线程同步">线程同步</h6>
<p><strong>同步代码块</strong></p>
<p>作用：把出现线程安全问题的核心代码给上锁。</p>
<p>原理：每次只能一个线程进入，执行完毕后自动解锁，其他线程才可以进来执行。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">synchronized</span>(同步锁对象) &#123;<br>  操作共享资源的代码(核心代码)<br> &#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">      小明 小红</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">drawMoney</span><span class="hljs-params">(<span class="hljs-type">double</span> money)</span> &#123;<br>        <span class="hljs-comment">// 1、拿到是谁来取钱</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> Thread.currentThread().getName();<br>        <span class="hljs-comment">// 同步代码块</span><br>        <span class="hljs-comment">// 小明 小红</span><br>        <span class="hljs-comment">// this == acc 共享账户</span><br>        <span class="hljs-keyword">synchronized</span> (<span class="hljs-built_in">this</span>) &#123;<br>            <span class="hljs-comment">// 2、判断余额是否足够</span><br>            <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.money &gt;= money)&#123;<br>                <span class="hljs-comment">// 钱够了</span><br>                System.out.println(name+<span class="hljs-string">&quot;来取钱，吐出：&quot;</span> + money);<br>                <span class="hljs-comment">// 更新余额</span><br>                <span class="hljs-built_in">this</span>.money -= money;<br>                System.out.println(name+<span class="hljs-string">&quot;取钱后，余额剩余：&quot;</span> + <span class="hljs-built_in">this</span>.money);<br>            &#125;<span class="hljs-keyword">else</span>&#123;<br>                <span class="hljs-comment">// 3、余额不足</span><br>                System.out.println(name+<span class="hljs-string">&quot;来取钱，余额不足！&quot;</span>);<br>            &#125;<br>        &#125;<br>    &#125;<br></code></pre></td></tr></table></figure>
<p><strong>锁对象的规范要求</strong></p>
<p>规范上：建议使用共享资源作为锁对象。</p>
<p>对于实例方法建议使用this作为锁对象。</p>
<p>对于静态方法建议使用字节码（类名.class）对象作为锁对象。</p>
<h6 id="同步方法"><strong>同步方法</strong></h6>
<p>作用：把出现线程安全问题的核心方法给上锁。</p>
<p>原理：每次只能一个线程进入，执行完毕以后自动解锁，其他线程才可以进来执行。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java">修饰符 <span class="hljs-keyword">synchronized</span> 返回值类型 方法名称(形参列表) &#123;<br>    操作共享资源的代码<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">      小明 小红</span><br><span class="hljs-comment">       this == acc</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">drawMoney</span><span class="hljs-params">(<span class="hljs-type">double</span> money)</span> &#123;<br>        <span class="hljs-comment">// 1、拿到是谁来取钱</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> Thread.currentThread().getName();<br>        <span class="hljs-comment">// 2、判断余额是否足够</span><br>        <span class="hljs-comment">// 小明  小红</span><br>        <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.money &gt;= money)&#123;<br>            <span class="hljs-comment">// 钱够了</span><br>            System.out.println(name+<span class="hljs-string">&quot;来取钱，吐出：&quot;</span> + money);<br>            <span class="hljs-comment">// 更新余额</span><br>            <span class="hljs-built_in">this</span>.money -= money;<br>            System.out.println(name+<span class="hljs-string">&quot;取钱后，余额剩余：&quot;</span> + <span class="hljs-built_in">this</span>.money);<br>        &#125;<span class="hljs-keyword">else</span>&#123;<br>            <span class="hljs-comment">// 3、余额不足</span><br>            System.out.println(name+<span class="hljs-string">&quot;来取钱，余额不足！&quot;</span>);<br>        &#125;<br>    &#125;<br></code></pre></td></tr></table></figure>
<p><strong>同步方法底层原理</strong></p>
<ul>
<li><p>同步方法其实底层也是有隐式锁对象的，只是锁的范围是整个方法代码。</p></li>
<li><p>如果方法是实例方法：同步方法默认用this作为的锁对象。但是代码要高度面向对象！</p></li>
<li><p>如果方法是静态方法：同步方法默认用类名.class作为的锁对象。</p></li>
</ul>
<h6 id="lock锁"><strong>Lock锁</strong></h6>
<ul>
<li><p>为了更清晰的表达如何加锁和释放锁，JDK5以后提供了一个新的锁对象Lock，更加灵活、方便。</p></li>
<li><p>Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。</p></li>
<li><p>Lock是接口不能直接实例化，这里采用它的实现类ReentrantLock来构建Lock锁对象。</p></li>
</ul>
<table>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public ReentrantLock()</td>
<td>获得Lock锁的实现类对象</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>void lock()</td>
<td>获得锁</td>
</tr>
<tr class="even">
<td>void unlock()</td>
<td>释放锁</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">// final修饰后：锁对象是唯一和不可替换的，非常专业</span><br>   <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-type">Lock</span> <span class="hljs-variable">lock</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ReentrantLock</span>();<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">     小明 小红</span><br><span class="hljs-comment">    */</span><br>   <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">drawMoney</span><span class="hljs-params">(<span class="hljs-type">double</span> money)</span> &#123;<br>       <span class="hljs-comment">// 1、拿到是谁来取钱</span><br>       <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> Thread.currentThread().getName();<br>       <span class="hljs-comment">// 2、判断余额是否足够</span><br>       <span class="hljs-comment">// 小明  小红</span><br>       lock.lock(); <span class="hljs-comment">// 上锁</span><br>       <span class="hljs-keyword">try</span> &#123;<br>           <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.money &gt;= money)&#123;<br>               <span class="hljs-comment">// 钱够了</span><br>               System.out.println(name+<span class="hljs-string">&quot;来取钱，吐出：&quot;</span> + money);<br>               <span class="hljs-comment">// 更新余额</span><br>               <span class="hljs-built_in">this</span>.money -= money;<br>               System.out.println(name+<span class="hljs-string">&quot;取钱后，余额剩余：&quot;</span> + <span class="hljs-built_in">this</span>.money);<br>           &#125;<span class="hljs-keyword">else</span>&#123;<br>               <span class="hljs-comment">// 3、余额不足</span><br>               System.out.println(name+<span class="hljs-string">&quot;来取钱，余额不足！&quot;</span>);<br>           &#125;<br>       &#125; <span class="hljs-keyword">finally</span> &#123;<br>           lock.unlock(); <span class="hljs-comment">// 解锁</span><br>       &#125;<br><br>   &#125;<br></code></pre></td></tr></table></figure>
<h6 id="线程通信">线程通信</h6>
<p><strong>什么是线程通信、如何实现？</strong></p>
<p>所谓线程通信就是线程间相互发送数据，线程间共享一个资源即可实现线程通信。</p>
<p><strong>线程通信常见形式</strong></p>
<p>通过共享一个数据的方式实现。</p>
<p>根据共享数据的情况决定自己该怎么做，以及通知其他线程怎么做。</p>
<p><strong>线程通信实际应用场景</strong></p>
<ul>
<li><p>生产者与消费者模型：生产者线程负责生产数据，消费者线程负责消费生产者产生的数据。</p></li>
<li><p>要求：生产者线程生产完数据后唤醒消费者，然后等待自己，消费者消费完该数据后唤醒生产者，然后等待自己。</p></li>
</ul>
<h6 id="线程通信案例模拟"><strong>线程通信案例模拟</strong></h6>
<p>模拟客服系统，系统可以不断的接入电话 和 分发给客服。</p>
<p>线程通信的前提：线程通信通常是在多个线程操作同一个共享资源的时候需要进行通信，且要保证线程安全。</p>
<table>
<colgroup>
<col style="width: 21%" />
<col style="width: 78%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>void wait()</td>
<td>让当前线程等待并释放所占锁，直到另一个线程调用notify()方法或
notifyAll()方法</td>
</tr>
<tr class="even">
<td>void notify()</td>
<td>唤醒正在等待的单个线程</td>
</tr>
<tr class="odd">
<td>void notifyAll()</td>
<td>唤醒正在等待的所有线程</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">	打电话线程</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CallThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 不断的打入电话</span><br>        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>)&#123;<br>            CallSystem.call();<br>        &#125;<br>    &#125;<br>&#125;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">   接电话线程类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ReceiveThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-comment">// 1号  2号</span><br>        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>)&#123;<br>            CallSystem.receive();<br>        &#125;<br>    &#125;<br>&#125;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">	测试</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TestDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、生产者线程：负责不断接收打进来的电话</span><br>        <span class="hljs-type">CallThread</span> <span class="hljs-variable">call</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">CallThread</span>();<br>        call.start();<br><br>        <span class="hljs-comment">// 2、消费者线程：客服，每个客服每次接听一个电话</span><br>        <span class="hljs-type">ReceiveThread</span> <span class="hljs-variable">r1</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ReceiveThread</span>();<br>        r1.start();<br>    &#125;<br>&#125;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">   呼叫系统。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CallSystem</span> &#123;<br>    <span class="hljs-comment">// 定义一个变量记录当前呼入进来的电话。</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-type">int</span> <span class="hljs-variable">number</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; <span class="hljs-comment">// 最多只接听一个。</span><br><br>    <span class="hljs-comment">/* 接入电话</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">call</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            number++;<br>            System.out.println(<span class="hljs-string">&quot;成功接入一个用户，等待分发~~~~&quot;</span>);<br><br>            <span class="hljs-comment">// 唤醒别人 : 1个</span><br>            CallSystem.class.notify();<br>            <span class="hljs-comment">// 让当前线程对象进入等待状态。</span><br>            CallSystem.class.wait();<br><br>        &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       分发电话</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">receive</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> Thread.currentThread().getName();<br>            <span class="hljs-keyword">if</span>(number == <span class="hljs-number">1</span>)&#123;<br>                System.out.println(name + <span class="hljs-string">&quot;此电话已经分发给客服并接听完毕了~~~~~&quot;</span>);<br>                number--;<br>                <span class="hljs-comment">// 唤醒别人 : 1个</span><br>                CallSystem.class.notify();<br>                CallSystem.class.wait(); <span class="hljs-comment">// 让当前线程等待</span><br>            &#125;<span class="hljs-keyword">else</span> &#123;<br>                <span class="hljs-comment">// 唤醒别人 : 1个</span><br>                CallSystem.class.notify();<br>                CallSystem.class.wait(); <span class="hljs-comment">// 让当前线程等待</span><br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="线程池">线程池</h6>
<p>线程池就是一个可以复用线程的技术。</p>
<p><strong>不使用线程池的问题</strong></p>
<p>如果用户每发起一个请求，后台就创建一个新线程来处理，下次新任务来了又要创建新线程，而创建新线程的开销是很大的，这样会严重影响系统的性能。</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429161856082.png" srcset="/img/loading.gif" lazyload class="">
<p><strong>如何得到线程池对象</strong></p>
<p>方式一：使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象</p>
<figure>
<img
src="C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220429162111464.png" srcset="/img/loading.gif" lazyload
alt="image-20220429162111464" />
<figcaption aria-hidden="true">image-20220429162111464</figcaption>
</figure>
<p>方式二：使用Executors（线程池的工具类）调用方法返回不同特点的线程池对象</p>
<p><strong>ThreadPoolExecutor构造器的参数说明</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-title function_">ThreadPoolExecutor</span><span class="hljs-params">(</span><br><span class="hljs-params">							<span class="hljs-type">int</span> corePoolSize,</span><br><span class="hljs-params">							<span class="hljs-type">int</span> maximumPoolSize,</span><br><span class="hljs-params">							<span class="hljs-type">long</span> keepAliveTime,</span><br><span class="hljs-params">							TimeUnit unit,</span><br><span class="hljs-params">							BlockingQueue&lt;Runnable&gt; workQueue,                          </span><br><span class="hljs-params">							ThreadFactory threadFactory,                  				 											RejectedExecutionHandler handler)</span> <br></code></pre></td></tr></table></figure>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429162504314.png" srcset="/img/loading.gif" lazyload class="">
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MyRunnable</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Runnable</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">5</span>; i++) &#123;<br>            System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;输出了：HelloWorld ==&gt; &quot;</span>  + i);<br>        &#125;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;本任务与线程绑定了，线程进入休眠了~~~&quot;</span>);<br>            Thread.sleep(<span class="hljs-number">10000000</span>);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：自定义一个线程池对象，并测试其特性。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ThreadPoolDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、创建线程池对象</span><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">         public ThreadPoolExecutor(int corePoolSize,</span><br><span class="hljs-comment">                                 int maximumPoolSize,</span><br><span class="hljs-comment">                                 long keepAliveTime,</span><br><span class="hljs-comment">                                 TimeUnit unit,</span><br><span class="hljs-comment">                                 BlockingQueue&lt;Runnable&gt; workQueue,</span><br><span class="hljs-comment">                                 ThreadFactory threadFactory,</span><br><span class="hljs-comment">                                 RejectedExecutionHandler handler)</span><br><span class="hljs-comment">         */</span><br>        <span class="hljs-type">ExecutorService</span> <span class="hljs-variable">pool</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>(<span class="hljs-number">3</span>, <span class="hljs-number">5</span> ,<br>                <span class="hljs-number">6</span>, TimeUnit.SECONDS, <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayBlockingQueue</span>&lt;&gt;(<span class="hljs-number">5</span>) , Executors.defaultThreadFactory(),<br>               <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>.AbortPolicy() );<br><br>        <span class="hljs-comment">// 2、给任务线程池处理。</span><br>        <span class="hljs-type">Runnable</span> <span class="hljs-variable">target</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MyRunnable</span>();<br>        <span class="hljs-comment">//线程池工作线程</span><br>        pool.execute(target);<br>        pool.execute(target);<br>        pool.execute(target);<br>		<span class="hljs-comment">//线程队列</span><br>        pool.execute(target);<br>        pool.execute(target);<br>        pool.execute(target);<br>        pool.execute(target);<br>        pool.execute(target);<br><br>        <span class="hljs-comment">// 创建临时线程</span><br>        pool.execute(target);<br>        pool.execute(target);<br><span class="hljs-comment">//        // 不创建，拒绝策略被触发！！！</span><br><span class="hljs-comment">//        pool.execute(target);</span><br><br>        <span class="hljs-comment">// 关闭线程池（开发中一般不会使用）。</span><br>        <span class="hljs-comment">// pool.shutdownNow(); // 立即关闭，即使任务没有完成，会丢失任务的！</span><br>        pool.shutdown(); <span class="hljs-comment">// 会等待全部任务执行完毕之后再关闭（建议使用的）</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<table>
<colgroup>
<col style="width: 36%" />
<col style="width: 63%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>void execute(Runnable command)</td>
<td>执行任务/命令，没有返回值，一般用来执行 Runnable 任务</td>
</tr>
<tr class="even">
<td>Future<T> submit(Callable<T> task)</td>
<td>执行任务，返回未来任务对象获取线程结果，一般拿来执行 Callable
任务</td>
</tr>
<tr class="odd">
<td>void shutdown()</td>
<td>等任务执行完毕后关闭线程池</td>
</tr>
<tr class="even">
<td>List&lt;[Runnable]&gt;shutdownNow()</td>
<td>立刻关闭，停止正在执行的任务，并返回队列中未执行的任务</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：自定义一个线程池对象，并测试其特性。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ThreadPoolDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建线程池对象</span><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">         public ThreadPoolExecutor(int corePoolSize,</span><br><span class="hljs-comment">                                 int maximumPoolSize,</span><br><span class="hljs-comment">                                 long keepAliveTime,</span><br><span class="hljs-comment">                                 TimeUnit unit,</span><br><span class="hljs-comment">                                 BlockingQueue&lt;Runnable&gt; workQueue,</span><br><span class="hljs-comment">                                 ThreadFactory threadFactory,</span><br><span class="hljs-comment">                                 RejectedExecutionHandler handler)</span><br><span class="hljs-comment">         */</span><br>        <span class="hljs-type">ExecutorService</span> <span class="hljs-variable">pool</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>(<span class="hljs-number">3</span>, <span class="hljs-number">5</span> ,<br>                <span class="hljs-number">6</span>, TimeUnit.SECONDS, <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayBlockingQueue</span>&lt;&gt;(<span class="hljs-number">5</span>) , Executors.defaultThreadFactory(),<br>               <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>.AbortPolicy() );<br><br>        <span class="hljs-comment">// 2、给任务线程池处理。</span><br>        Future&lt;String&gt; f1 = pool.submit(<span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">100</span>));<br>        Future&lt;String&gt; f2 = pool.submit(<span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">200</span>));<br>        Future&lt;String&gt; f3 = pool.submit(<span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">300</span>));<br>        Future&lt;String&gt; f4 = pool.submit(<span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">400</span>));<br>        Future&lt;String&gt; f5 = pool.submit(<span class="hljs-keyword">new</span> <span class="hljs-title class_">MyCallable</span>(<span class="hljs-number">500</span>));<br><br><span class="hljs-comment">//        String rs = f1.get();</span><br><span class="hljs-comment">//        System.out.println(rs);</span><br><br>        System.out.println(f1.get());<br>        System.out.println(f2.get());<br>        System.out.println(f3.get());<br>        System.out.println(f4.get());<br>        System.out.println(f5.get());<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="executors得到线程池对象的常用方法"><strong>Executors得到线程池对象的常用方法</strong></h6>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ExecutorService.html">ExecutorService</a>
newCachedThreadPool()</td>
<td>线程数量随着任务增加而增加，如果线程任务执行完毕且空闲了一段时间则会被回收掉。</td>
</tr>
<tr class="even">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ExecutorService.html">ExecutorService</a>
newFixedThreadPool(int nThreads)</td>
<td>创建固定线程数量的线程池，如果某个线程因为执行异常而结束，那么线程池会补充一个新线程替代它。</td>
</tr>
<tr class="odd">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ExecutorService.html">ExecutorService</a>
newSingleThreadExecutor ()</td>
<td>创建只有一个线程的线程池对象，如果该线程出现异常而结束，那么线程池会补充一个新线程。</td>
</tr>
<tr class="even">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ScheduledExecutorService.html">ScheduledExecutorService</a>
newScheduledThreadPool(int corePoolSize)</td>
<td>创建一个线程池，可以实现在给定的延迟后运行任务，或者定期执行任务。</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名称</th>
<th>存在问题</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ExecutorService.html">ExecutorService</a>
newFixedThreadPool(int nThreads)</td>
<td>允许请求的任务队列长度是Integer.MAX_VALUE，可能出现OOM错误（
java.lang.OutOfMemoryError ）</td>
</tr>
<tr class="even">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ExecutorService.html">ExecutorService</a>
newSingleThreadExecutor()</td>
<td>同上</td>
</tr>
<tr class="odd">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ExecutorService.html">ExecutorService</a>
newCachedThreadPool()</td>
<td>创建的线程数量最大上限是Integer.MAX_VALUE，
线程数可能会随着任务1:1增长，也可能出现OOM错误（
java.lang.OutOfMemoryError ）</td>
</tr>
<tr class="even">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/util/concurrent/ScheduledExecutorService.html">ScheduledExecutorService</a>
newScheduledThreadPool(int corePoolSize)</td>
<td>同上</td>
</tr>
</tbody>
</table>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429165534998.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="定时器"><strong>定时器</strong></h6>
<p>定时器是一种控制任务延时调用，或者周期调用的技术。</p>
<p>作用：闹钟、定时邮件发送。</p>
<p><strong>定时器的实现方式</strong></p>
<p>方式一：Timer</p>
<p>方式二： ScheduledExecutorService</p>
<table>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public Timer()</td>
<td>创建Timer定时器对象</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 59%" />
<col style="width: 40%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void schedule(<a
href="file:///D:/course/%E5%9F%BA%E7%A1%80%E9%98%B6%E6%AE%B5/API%E6%96%87%E6%A1%A3/docs/api/java.base/java/util/TimerTask.html">TimerTask</a>
task, long delay, long period)</td>
<td>开启一个定时器，按照计划处理TimerTask任务</td>
</tr>
</tbody>
</table>
<p><strong>Timer定时器的特点和存在的问题</strong></p>
<p>1、Timer是单线程，处理多个任务按照顺序执行，存在延时与设置定时器的时间有出入。</p>
<p>2、可能因为其中的某个任务的异常使Timer线程死掉，从而影响后续任务执行。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Timer定时器的使用和了解。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TimerDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、创建Timer定时器</span><br>        <span class="hljs-type">Timer</span> <span class="hljs-variable">timer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Timer</span>();  <span class="hljs-comment">// 定时器本身就是一个单线程。</span><br>        <span class="hljs-comment">// 2、调用方法，处理定时任务</span><br>        timer.schedule(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;执行AAA~~~&quot;</span> + <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());<br><span class="hljs-comment">//                try &#123;</span><br><span class="hljs-comment">//                    Thread.sleep(5000);</span><br><span class="hljs-comment">//                &#125; catch (InterruptedException e) &#123;</span><br><span class="hljs-comment">//                    e.printStackTrace();</span><br><span class="hljs-comment">//                &#125;</span><br>            &#125;<br>        &#125;, <span class="hljs-number">0</span>, <span class="hljs-number">2000</span>);<br><br>        timer.schedule(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;执行BB~~~&quot;</span>+ <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());<br>                System.out.println(<span class="hljs-number">10</span>/<span class="hljs-number">0</span>);<br>            &#125;<br>        &#125;, <span class="hljs-number">0</span>, <span class="hljs-number">2000</span>);<br><br>        timer.schedule(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;执行CCC~~~&quot;</span>+ <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());<br>            &#125;<br>        &#125;, <span class="hljs-number">0</span>, <span class="hljs-number">3000</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="scheduledexecutorservice定时器"><strong>ScheduledExecutorService定时器</strong></h6>
<table>
<colgroup>
<col style="width: 81%" />
<col style="width: 18%" />
</colgroup>
<thead>
<tr class="header">
<th>Executors的方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public static ScheduledExecutorService newScheduledThreadPool(int
corePoolSize)</td>
<td>得到线程池对象</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 83%" />
<col style="width: 16%" />
</colgroup>
<thead>
<tr class="header">
<th>ScheduledExecutorService的方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public ScheduledFuture&lt;?&gt; scheduleAtFixedRate(Runnable
command, long initialDelay, long period, TimeUnit unit)</td>
<td>周期调度方法</td>
</tr>
</tbody>
</table>
<p><strong>ScheduledExecutorService的优点</strong></p>
<p>1、基于线程池，某个任务的执行情况不会影响其他定时任务的执行。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：Timer定时器的使用和了解。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TimerDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、创建ScheduledExecutorService线程池，做定时器</span><br>        <span class="hljs-type">ScheduledExecutorService</span> <span class="hljs-variable">pool</span> <span class="hljs-operator">=</span> Executors.newScheduledThreadPool(<span class="hljs-number">3</span>);<br><br>        <span class="hljs-comment">// 2、开启定时任务</span><br>        pool.scheduleAtFixedRate(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;执行输出：AAA  ==》 &quot;</span> + <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());<br>                <span class="hljs-keyword">try</span> &#123;<br>                    Thread.sleep(<span class="hljs-number">100000</span>);<br>                &#125; <span class="hljs-keyword">catch</span> (InterruptedException e) &#123;<br>                    e.printStackTrace();<br>                &#125;<br>            &#125;<br>        &#125;, <span class="hljs-number">0</span>, <span class="hljs-number">2</span>, TimeUnit.SECONDS);<br><br><br>        pool.scheduleAtFixedRate(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;执行输出：BBB  ==》 &quot;</span> + <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());<br>                <span class="hljs-comment">//该线程挂了，其他线程不挂</span><br>                System.out.println(<span class="hljs-number">10</span> / <span class="hljs-number">0</span>);<br>            &#125;<br>        &#125;, <span class="hljs-number">0</span>, <span class="hljs-number">2</span>, TimeUnit.SECONDS);<br><br><br>        pool.scheduleAtFixedRate(<span class="hljs-keyword">new</span> <span class="hljs-title class_">TimerTask</span>() &#123;<br>            <span class="hljs-meta">@Override</span><br>            <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>                System.out.println(Thread.currentThread().getName() + <span class="hljs-string">&quot;执行输出：CCC  ==》 &quot;</span> + <span class="hljs-keyword">new</span> <span class="hljs-title class_">Date</span>());<br>            &#125;<br>        &#125;, <span class="hljs-number">0</span>, <span class="hljs-number">2</span>, TimeUnit.SECONDS);<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="并发与并行"><strong>并发与并行</strong></h6>
<p>正在运行的程序（软件）就是一个独立的进程，
线程是属于进程的，多个线程其实是并发与并行同时进行的。</p>
<p><strong>并发的理解：</strong></p>
<ul>
<li><p>CPU同时处理线程的数量有限。</p></li>
<li><p>CPU会轮询为系统的每个线程服务，由于CPU切换的速度很快，给我们的感觉这些线程在同时执行，这就是并发。</p></li>
</ul>
<p><strong>并行的理解：</strong></p>
<ul>
<li>在同一个时刻上，同时有多个线程在被CPU处理并执行。</li>
</ul>
<h6 id="线程的状态"><strong>线程的状态</strong></h6>
<ul>
<li><p>线程的状态：也就是线程从生到死的过程，以及中间经历的各种状态及状态转换。</p></li>
<li><p>理解线程的状态有利于提升并发编程的理解能力。</p></li>
</ul>
<table>
<colgroup>
<col style="width: 27%" />
<col style="width: 72%" />
</colgroup>
<thead>
<tr class="header">
<th>NEW(新建)</th>
<th>解释</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>NEW(新建)</td>
<td>线程刚被创建，但是并未启动。</td>
</tr>
<tr class="even">
<td>Runnable(可运行)</td>
<td>线程已经调用了start()等待CPU调度</td>
</tr>
<tr class="odd">
<td>Blocked(锁阻塞)</td>
<td>线程在执行的时候未竞争到锁对象，则该线程进入Blocked状态；。</td>
</tr>
<tr class="even">
<td>Waiting(无限等待)</td>
<td>一个线程进入Waiting状态，另一个线程调用notify或者notifyAll方法才能够唤醒</td>
</tr>
<tr class="odd">
<td>Timed Waiting(计时等待)</td>
<td>同waiting状态，有几个方法有超时参数，调用他们将进入Timed
Waiting状态。带有超时参数的常用方法有Thread.sleep 、Object.wait。</td>
</tr>
<tr class="even">
<td>Teminated(被终止)</td>
<td>因为run方法正常退出而死亡，或者因为没有捕获的异常终止了run方法而死亡。</td>
</tr>
</tbody>
</table>
<h4 id="网络编程">网络编程</h4>
<p>常见的通信模式有如下2种形式：Client-Server(CS)
、Browser/Server(BS)</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429174326693.png" srcset="/img/loading.gif" lazyload class="">
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429174340243.png" srcset="/img/loading.gif" lazyload class="">
<h6
id="实现网络编程关键的三要素"><strong>实现网络编程关键的三要素</strong></h6>
<p><strong>IP地址</strong>：设备在网络中的地址，是唯一的标识。</p>
<p><strong>端口：</strong>应用程序在设备中唯一的标识。</p>
<p><strong>协议</strong>:
数据在网络中传输的规则，常见的协议有UDP协议和TCP协议。</p>
<p><strong>IP地址</strong></p>
<p>IPv6：128位（16个字节），号称可以为地球每一粒沙子编号。</p>
<p>IPv6分成8个整数，每个整数用四个十六进制位表示，
数之间用冒号（：）分开。</p>
<p><strong>IP地址形式：</strong></p>
<p>公网地址、和私有地址(局域网使用)。</p>
<p>192.168.
开头的就是常见的局域网地址，范围即为192.168.0.0--192.168.255.255，专门为组织机构内部使用。</p>
<p><strong>IP常用命令：</strong></p>
<p>ipconfig：查看本机IP地址</p>
<p>ping IP地址：检查网络是否连通</p>
<p><strong>特殊IP地址</strong>：</p>
<p>本机IP:
127.0.0.1或者localhost：称为回送地址也可称本地回环地址，只会寻找当前所在本机。</p>
<h6 id="inetaddress-的使用"><strong>InetAddress</strong>
<strong>的使用</strong></h6>
<table>
<colgroup>
<col style="width: 55%" />
<col style="width: 44%" />
</colgroup>
<thead>
<tr class="header">
<th>名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public static <a
href="mk:@MSITStore:D:\course\jdk-11中文api修订版.CHM::/java.base/java/net/InetAddress.html">InetAddress</a>
getLocalHost()</td>
<td>返回本主机的地址对象</td>
</tr>
<tr class="even">
<td>public static InetAddress getByName(String host)</td>
<td>得到指定主机的IP地址对象，参数是域名或者IP地址</td>
</tr>
<tr class="odd">
<td>public String getHostName()</td>
<td>获取此IP地址的主机名</td>
</tr>
<tr class="even">
<td>public String getHostAddress()</td>
<td>返回IP地址字符串</td>
</tr>
<tr class="odd">
<td>public boolean isReachable(int timeout)</td>
<td>在指定毫秒内连通该IP地址对应的主机，连通返回true</td>
</tr>
</tbody>
</table>
<h6 id="端口号"><strong>端口号</strong></h6>
<p>l端口号：标识正在计算机设备上运行的进程（程序），被规定为一个 16
位的二进制，范围是 0~65535。</p>
<p><strong>端口类型</strong></p>
<p>周知端口：0~1023，被预先定义的知名应用占用（如：HTTP占用
80，FTP占用21）</p>
<p><strong>注册端口</strong>：1024~49151，分配给用户进程或某些应用程序。（如：Tomcat占
用8080，MySQL占用3306）</p>
<p>动态端口：49152到65535，之所以称为动态端口，是因为它
一般不固定分配某种进程，而是动态分配。</p>
<p><strong>注意：我们自己开发的程序选择注册端口，且一个设备中不能出现两个程序的端口号一样，否则出错。</strong></p>
<h6
id="网络通信协议有两套参考模型"><strong>网络通信协议有两套参考模型</strong></h6>
<ul>
<li><p>OSI参考模型：世界互联协议标准，全球通信规范，由于此模型过于理想化，未能在因特网上进行广泛推广。</p></li>
<li><p>TCP/IP参考模型(或TCP/IP协议)：事实上的国际标准。</p></li>
</ul>
<table>
<colgroup>
<col style="width: 10%" />
<col style="width: 14%" />
<col style="width: 20%" />
<col style="width: 54%" />
</colgroup>
<thead>
<tr class="header">
<th>OSI参考模型</th>
<th>TCP/IP参考模型</th>
<th>各层对应</th>
<th>面向操作</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>应用层</td>
<td>应用层</td>
<td>HTTP、FTP、DNS、SMTP…</td>
<td>应用程序需要关注的：浏览器，邮箱。程序员一般在这一层开发</td>
</tr>
<tr class="even">
<td>表示层</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="odd">
<td>会话层</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="even">
<td>传输层</td>
<td>传输层</td>
<td>TCP、UDP…</td>
<td>选择使用的TCP , UDP协议</td>
</tr>
<tr class="odd">
<td>网络层</td>
<td>网络层</td>
<td>IP、ICMP…</td>
<td>封装源和目标IP，进行路径选择</td>
</tr>
<tr class="even">
<td>数据链路层</td>
<td>数据链路层+物理</td>
<td>物理寻址、比特流…</td>
<td>物理设备中传输</td>
</tr>
<tr class="odd">
<td>物理层</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p><strong>TCP协议特点</strong></p>
<ul>
<li><p>使用TCP协议，必须双方先建立连接，它是一种面向连接的可靠通信协议。</p></li>
<li><p>传输前，采用“三次握手”方式建立连接，所以是可靠的 。</p></li>
<li><p>在连接中可进行大数据量的传输 。</p></li>
<li><p>连接、发送数据都需要确认，且传输完毕后，还需释放已建立的连接，通信效率较低。</p></li>
</ul>
<p><strong>TCP协议通信场景</strong></p>
<ul>
<li>对信息安全要求较高的场景，例如：文件下载、金融等数据通信。</li>
</ul>
<p><strong>UDP协议：</strong></p>
<ul>
<li><p>UDP是一种无连接、不可靠传输的协议。</p></li>
<li><p>将数据源IP、目的地IP和端口封装成数据包，不需要建立连接</p></li>
<li><p>每个数据包的大小限制在64KB内</p></li>
<li><p>发送不管对方是否准备好，接收方收到也不确认，故是不可靠的</p></li>
<li><p>可以广播发送
，发送数据结束时无需释放资源，开销小，速度快。</p></li>
</ul>
<p><strong>UDP协议通信场景</strong></p>
<ul>
<li>语音通话，视频会话等。</li>
</ul>
<h6 id="udp">UDP</h6>
<p><strong>DatagramPacket：数据包对象（韭菜盘子）</strong></p>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public DatagramPacket(byte[] buf, int length, InetAddress address,
int port)</td>
<td>创建发送端数据包对象 buf：要发送的内容，字节数组
length：要发送内容的字节长度 address：接收端的IP地址对象
port：接收端的端口号</td>
</tr>
<tr class="even">
<td>public DatagramPacket(byte[] buf, int length)</td>
<td>创建接收端的数据包对象 buf：用来存储接收的内容
length：能够接收内容的长度</td>
</tr>
</tbody>
</table>
<p><strong>DatagramSocket类成员方法</strong></p>
<table>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public void send(DatagramPacket dp)</td>
<td>发送数据包</td>
</tr>
<tr class="even">
<td>public void receive(DatagramPacket p)</td>
<td>接收数据包</td>
</tr>
</tbody>
</table>
<p>需求：客户端实现步骤</p>
<p>①创建DatagramSocket对象（发送端对象） 扔韭菜的人</p>
<p>②创建DatagramPacket对象封装需要发送的数据（数据包对象） 韭菜盘子</p>
<p>③使用DatagramSocket对象的send方法传入DatagramPacket对象
开始抛出韭菜</p>
<p>④释放资源</p>
<p>需求：接收端实现步骤</p>
<p>①创建DatagramSocket对象并指定端口（接收端对象） 接韭菜的人</p>
<p>②创建DatagramPacket对象接收数据（数据包对象） 韭菜盘子</p>
<p>③使用DatagramSocket对象的receive方法传入DatagramPacket对象
开始接收韭菜</p>
<p>④释放资源</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  发送端  一发 一收</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ClientDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        System.out.println(<span class="hljs-string">&quot;=====客户端启动======&quot;</span>);<br><br>        <span class="hljs-comment">// 1、创建发送端对象：发送端自带默认的端口号（人）</span><br>        <span class="hljs-type">DatagramSocket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramSocket</span>(<span class="hljs-number">6666</span>);<br><br>        <span class="hljs-comment">// 2、创建一个数据包对象封装数据（韭菜盘子）</span><br>        <span class="hljs-comment">/**</span><br><span class="hljs-comment">         public DatagramPacket(byte buf[], int length,</span><br><span class="hljs-comment">         InetAddress address, int port)</span><br><span class="hljs-comment">         参数一：封装要发送的数据（韭菜）</span><br><span class="hljs-comment">         参数二：发送数据的大小</span><br><span class="hljs-comment">         参数三：服务端的主机IP地址</span><br><span class="hljs-comment">         参数四：服务端的端口</span><br><span class="hljs-comment">         */</span><br>        <span class="hljs-type">byte</span>[] buffer = <span class="hljs-string">&quot;我是一颗快乐的韭菜，你愿意吃吗？&quot;</span>.getBytes();<br>        <span class="hljs-type">DatagramPacket</span> <span class="hljs-variable">packet</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramPacket</span>( buffer, buffer.length,<br>                InetAddress.getLocalHost() , <span class="hljs-number">8888</span>);<br><br>        <span class="hljs-comment">// 3、发送数据出去</span><br>        socket.send(packet);<br><br>        socket.close();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  接收端</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        System.out.println(<span class="hljs-string">&quot;=====服务端启动======&quot;</span>);<br>        <span class="hljs-comment">// 1、创建接收端对象：注册端口（人）</span><br>        <span class="hljs-type">DatagramSocket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramSocket</span>(<span class="hljs-number">8888</span>);<br><br>        <span class="hljs-comment">// 2、创建一个数据包对象接收数据（韭菜盘子）</span><br>        <span class="hljs-type">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">1024</span> * <span class="hljs-number">64</span>];<br>        <span class="hljs-type">DatagramPacket</span> <span class="hljs-variable">packet</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramPacket</span>(buffer, buffer.length);<br><br>        <span class="hljs-comment">// 3、等待接收数据。</span><br>        socket.receive(packet);<br><br>        <span class="hljs-comment">// 4、取出数据即可</span><br>        <span class="hljs-comment">// 读取多少倒出多少</span><br>        <span class="hljs-type">int</span> <span class="hljs-variable">len</span> <span class="hljs-operator">=</span> packet.getLength();<br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(buffer,<span class="hljs-number">0</span>, len);<br>        System.out.println(<span class="hljs-string">&quot;收到了：&quot;</span> + rs);<br><br>        <span class="hljs-comment">// 获取发送端的ip和端口</span><br>        <span class="hljs-type">String</span> <span class="hljs-variable">ip</span>  <span class="hljs-operator">=</span>packet.getSocketAddress().toString();<br>        System.out.println(<span class="hljs-string">&quot;对方地址：&quot;</span> + ip);<br><br>        <span class="hljs-type">int</span> <span class="hljs-variable">port</span>  <span class="hljs-operator">=</span> packet.getPort();<br>        System.out.println(<span class="hljs-string">&quot;对方端口：&quot;</span> + port);<br><br>        socket.close();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="udp的三种通信方式"><strong>UDP的三种通信方式</strong></h6>
<p>单播：单台主机与单台主机之间的通信。</p>
<p>广播：当前主机与所在网络中的所有主机通信。</p>
<p>组播：当前主机与选定的一组主机的通信。</p>
<h6 id="udp如何实现广播"><strong>UDP如何实现广播</strong></h6>
<p>使用广播地址：255.255.255.255</p>
<p>具体操作：</p>
<p>①发送端发送的数据包的目的地写的是广播地址、且指定端口。
（255.255.255.255 , 9999）</p>
<p>②本机所在网段的其他主机的程序只要注册对应端口就可以收到消息了。（9999）</p>
<h6 id="udp如何实现组播"><strong>UDP如何实现组播</strong></h6>
<p>使用组播地址：224.0.0.0 ~ 239.255.255.255</p>
<p>具体操作：</p>
<p>①发送端的数据包的目的地是组播IP (例如：224.0.1.1, 端口：9999)</p>
<p>②接收端必须绑定该组播IP(224.0.1.1)，端口还要注册发送端的目的端口9999
，这样即可接收该组播消息。</p>
<p>③DatagramSocket的子类MulticastSocket可以在接收端绑定组播IP。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs java"><br>            <span class="hljs-comment">// 2、创建一个数据包对象封装数据（韭菜盘子）</span><br>            <span class="hljs-type">byte</span>[] buffer = msg.getBytes();<br>            <span class="hljs-comment">// 注意：只要目的地IP是 255.255.255.255 这个消息将以广播的形式对外发送</span><br><span class="hljs-comment">//            DatagramPacket packet = new DatagramPacket( buffer, buffer.length,</span><br><span class="hljs-comment">//                    InetAddress.getByName(&quot;255.255.255.255&quot;) , 8888);</span><br><br>            <span class="hljs-type">DatagramPacket</span> <span class="hljs-variable">packet</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramPacket</span>( buffer, buffer.length,<br>                    InetAddress.getByName(<span class="hljs-string">&quot;224.0.1.1&quot;</span>) , <span class="hljs-number">9898</span>);<br><br>                    <span class="hljs-comment">// 3、发送数据出去</span><br>            socket.send(packet);<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  接收端,广播</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        System.out.println(<span class="hljs-string">&quot;=====服务端启动======&quot;</span>);<br>        <span class="hljs-comment">// 1、创建接收端对象：注册端口（人）</span><br>        <span class="hljs-type">DatagramSocket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramSocket</span>(<span class="hljs-number">8888</span>);<br><br>        <span class="hljs-comment">// 2、创建一个数据包对象接收数据（韭菜盘子）</span><br>        <span class="hljs-type">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">1024</span> * <span class="hljs-number">64</span>];<br>        <span class="hljs-type">DatagramPacket</span> <span class="hljs-variable">packet</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramPacket</span>(buffer, buffer.length);<br><br>        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>            <span class="hljs-comment">// 3、等待接收数据。</span><br>            socket.receive(packet);<br>            <span class="hljs-comment">// 4、取出数据即可</span><br>            <span class="hljs-comment">// 读取多少倒出多少</span><br>            <span class="hljs-type">int</span> <span class="hljs-variable">len</span> <span class="hljs-operator">=</span> packet.getLength();<br>            <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(buffer,<span class="hljs-number">0</span>, len);<br>            System.out.println(<span class="hljs-string">&quot;收到了来自：&quot;</span> + packet.getAddress() +<span class="hljs-string">&quot;, 对方端口是&quot;</span> + packet.getPort() +<span class="hljs-string">&quot;的消息：&quot;</span> + rs);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">  接收端，组播</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo3</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        System.out.println(<span class="hljs-string">&quot;=====服务端启动======&quot;</span>);<br>        <span class="hljs-comment">// 1、创建接收端对象：注册端口（人）</span><br>        <span class="hljs-type">MulticastSocket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">MulticastSocket</span>(<span class="hljs-number">9898</span>);<br><br>        <span class="hljs-comment">// 注意：绑定组播地址（加群）</span><br>        socket.joinGroup(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InetSocketAddress</span>(InetAddress.getByName(<span class="hljs-string">&quot;224.0.1.1&quot;</span>) , <span class="hljs-number">9898</span>),<br>                NetworkInterface.getByInetAddress(InetAddress.getLocalHost()));<br><br>        <span class="hljs-comment">// 2、创建一个数据包对象接收数据（韭菜盘子）</span><br>        <span class="hljs-type">byte</span>[] buffer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">1024</span> * <span class="hljs-number">64</span>];<br>        <span class="hljs-type">DatagramPacket</span> <span class="hljs-variable">packet</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">DatagramPacket</span>(buffer, buffer.length);<br><br><br>        <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>            <span class="hljs-comment">// 3、等待接收数据。</span><br>            socket.receive(packet);<br>            <span class="hljs-comment">// 4、取出数据即可</span><br>            <span class="hljs-comment">// 读取多少倒出多少</span><br>            <span class="hljs-type">int</span> <span class="hljs-variable">len</span> <span class="hljs-operator">=</span> packet.getLength();<br>            <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>(buffer,<span class="hljs-number">0</span>, len);<br>            System.out.println(<span class="hljs-string">&quot;收到了来自：&quot;</span> + packet.getAddress() +<span class="hljs-string">&quot;, 对方端口是&quot;</span> + packet.getPort() +<span class="hljs-string">&quot;的消息：&quot;</span> + rs);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="tcp">TCP</h6>
<ul>
<li><p>TCP是一种面向连接，安全、可靠的传输数据的协议</p></li>
<li><p>传输前，采用“三次握手”方式，点对点通信，是可靠的</p></li>
<li><p>在连接中可进行大数据量的传输</p></li>
</ul>
<h6 id="socket"><strong>Socket</strong></h6>
<table>
<colgroup>
<col style="width: 38%" />
<col style="width: 61%" />
</colgroup>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public Socket(String host , int port)</td>
<td>创建发送端的Socket对象与服务端连接，参数为服务端程序的ip和端口。</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>OutputStream getOutputStream()</td>
<td>获得字节输出流对象</td>
</tr>
<tr class="even">
<td>InputStream getInputStream()</td>
<td>获得字节输入流对象</td>
</tr>
</tbody>
</table>
<h6 id="客户端发送消息">客户端发送消息</h6>
<p>需求：客户端实现步骤</p>
<p>①创建客户端的Socket对象，请求与服务端的连接。</p>
<p>②使用socket对象调用getOutputStream()方法得到字节输出流。</p>
<p>③使用字节输出流完成数据的发送。</p>
<p>④释放资源：关闭socket管道。</p>
<p><strong>ServerSocket(服务端)</strong></p>
<table>
<thead>
<tr class="header">
<th>构造器</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public ServerSocket(int port)</td>
<td>注册服务端端口</td>
</tr>
</tbody>
</table>
<table>
<colgroup>
<col style="width: 26%" />
<col style="width: 73%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public Socket accept()</td>
<td>等待接收客户端的Socket通信连接
连接成功返回Socket对象与客户端建立端到端通信</td>
</tr>
</tbody>
</table>
<h6 id="服务端实现接收消息">服务端实现接收消息</h6>
<p>需求：服务端实现步骤</p>
<p>①创建ServerSocket对象，注册服务端端口。</p>
<p>②调用ServerSocket对象的accept()方法，等待客户端的连接，并得到Socket管道对象。</p>
<p>③通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。</p>
<p>④释放资源：关闭socket管道</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：完成Socket网络编程入门案例的客户端开发，实现1发1收。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ClientDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;====客户端启动===&quot;</span>);<br>            <span class="hljs-comment">// 1、创建Socket通信管道请求有服务端的连接</span><br>            <span class="hljs-comment">// public Socket(String host, int port)</span><br>            <span class="hljs-comment">// 参数一：服务端的IP地址</span><br>            <span class="hljs-comment">// 参数二：服务端的端口</span><br>            <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Socket</span>(<span class="hljs-string">&quot;127.0.0.1&quot;</span>, <span class="hljs-number">7777</span>);<br><br>            <span class="hljs-comment">// 2、从socket通信管道中得到一个字节输出流 负责发送数据</span><br>            <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> socket.getOutputStream();<br><br>            <span class="hljs-comment">// 3、把低级的字节流包装成打印流</span><br>            <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(os);<br><br>            <span class="hljs-comment">// 4、发送消息</span><br>            ps.println(<span class="hljs-string">&quot;我是TCP的客户端，我已经与你对接，并发出邀请：约吗？&quot;</span>);<br>            ps.flush();<br><br>            <span class="hljs-comment">// 关闭资源。</span><br>            <span class="hljs-comment">// socket.close();</span><br><br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：开发Socket网络编程入门代码的服务端，实现接收消息</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;===服务端启动成功===&quot;</span>);<br>            <span class="hljs-comment">// 1、注册端口</span><br>            <span class="hljs-type">ServerSocket</span> <span class="hljs-variable">serverSocket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerSocket</span>(<span class="hljs-number">7777</span>);<br>            <span class="hljs-comment">// 2、必须调用accept方法：等待接收客户端的Socket连接请求，建立Socket通信管道</span><br>            <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> serverSocket.accept();<br>            <span class="hljs-comment">// 3、从socket通信管道中得到一个字节输入流</span><br>            <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> socket.getInputStream();<br>            <span class="hljs-comment">// 4、把字节输入流包装成缓冲字符输入流进行消息的接收</span><br>            <span class="hljs-type">BufferedReader</span> <span class="hljs-variable">br</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedReader</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputStreamReader</span>(is));<br>            <span class="hljs-comment">// 5、按照行读取消息</span><br>            String msg;<br>            <span class="hljs-keyword">if</span> ((msg = br.readLine()) != <span class="hljs-literal">null</span>)&#123;<br>                System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;说了：: &quot;</span> + msg);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>1.TCP通信服务端用的代表类？</p>
<p><strong>ServerSocket类,注册端口。</strong></p>
<p><strong>调用accept()方法阻塞等待接收客户端连接。得到Socket对象。</strong></p>
<p>2.TCP通信的基本原理？</p>
<p><strong>客户端怎么发，服务端就应该怎么收。</strong></p>
<p><strong>客户端如果没有消息，服务端会进入阻塞等待。</strong></p>
<p><strong>Socket一方关闭或者出现异常、对方Socket也会失效或者出错。</strong></p>
<p>1、之前我们的通信是否可以同时与多个客户端通信，为什么？</p>
<p><strong>不可以的</strong></p>
<p><strong>单线程每次只能处理一个客户端的Socket通信</strong></p>
<p>2、如何才可以让服务端可以处理多个客户端的通信需求？</p>
<p><strong>引入多线程。</strong></p>
<h6 id="多发多收">多发多收</h6>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220429203603902.png" srcset="/img/loading.gif" lazyload class="">
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：实现服务端可以同时处理多个客户端的消息。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ClientDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;====客户端启动===&quot;</span>);<br>            <span class="hljs-comment">// 1、创建Socket通信管道请求有服务端的连接</span><br>            <span class="hljs-comment">// public Socket(String host, int port)</span><br>            <span class="hljs-comment">// 参数一：服务端的IP地址</span><br>            <span class="hljs-comment">// 参数二：服务端的端口</span><br>            <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Socket</span>(<span class="hljs-string">&quot;127.0.0.1&quot;</span>, <span class="hljs-number">7777</span>);<br><br>            <span class="hljs-comment">// 2、从socket通信管道中得到一个字节输出流 负责发送数据</span><br>            <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> socket.getOutputStream();<br><br>            <span class="hljs-comment">// 3、把低级的字节流包装成打印流</span><br>            <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(os);<br><br>            <span class="hljs-type">Scanner</span> <span class="hljs-variable">sc</span> <span class="hljs-operator">=</span>  <span class="hljs-keyword">new</span> <span class="hljs-title class_">Scanner</span>(System.in);<br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                System.out.println(<span class="hljs-string">&quot;请说：&quot;</span>);<br>                <span class="hljs-type">String</span> <span class="hljs-variable">msg</span> <span class="hljs-operator">=</span> sc.nextLine();<br>                <span class="hljs-comment">// 4、发送消息</span><br>                ps.println(msg);<br>                ps.flush();<br>            &#125;<br><br>            <span class="hljs-comment">// 关闭资源。</span><br>            <span class="hljs-comment">// socket.close();</span><br><br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：实现服务端可以同时处理多个客户端的消息。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo2</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;===服务端启动成功===&quot;</span>);<br>            <span class="hljs-comment">// 1、注册端口</span><br>            <span class="hljs-type">ServerSocket</span> <span class="hljs-variable">serverSocket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerSocket</span>(<span class="hljs-number">7777</span>);<br>            <span class="hljs-comment">// a.定义一个死循环由主线程负责不断的接收客户端的Socket管道连接。</span><br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                <span class="hljs-comment">// 2、每接收到一个客户端的Socket管道，交给一个独立的子线程负责读取消息</span><br>                <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> serverSocket.accept();<br>                System.out.println(socket.getRemoteSocketAddress()+ <span class="hljs-string">&quot;它来了，上线了！&quot;</span>);<br>                <span class="hljs-comment">// 3、开始创建独立线程处理socket</span><br>                <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerReaderThread</span>(socket).start();<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerReaderThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span>&#123;<br>    <span class="hljs-keyword">private</span> Socket socket;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ServerReaderThread</span><span class="hljs-params">(Socket socket)</span>&#123;<br>        <span class="hljs-built_in">this</span>.socket = socket;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 3、从socket通信管道中得到一个字节输入流</span><br>            <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> socket.getInputStream();<br>            <span class="hljs-comment">// 4、把字节输入流包装成缓冲字符输入流进行消息的接收</span><br>            <span class="hljs-type">BufferedReader</span> <span class="hljs-variable">br</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedReader</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputStreamReader</span>(is));<br>            <span class="hljs-comment">// 5、按照行读取消息</span><br>            String msg;<br>            <span class="hljs-keyword">while</span> ((msg = br.readLine()) != <span class="hljs-literal">null</span>)&#123;<br>                System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;说了：: &quot;</span> + msg);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;下线了！！！&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="引入线程池">引入线程池</h6>
<p>解决N:N资源耗尽问题</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    拓展：使用线程池优化：实现通信。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ClientDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;====客户端启动===&quot;</span>);<br>            <span class="hljs-comment">// 1、创建Socket通信管道请求有服务端的连接</span><br>            <span class="hljs-comment">// public Socket(String host, int port)</span><br>            <span class="hljs-comment">// 参数一：服务端的IP地址</span><br>            <span class="hljs-comment">// 参数二：服务端的端口</span><br>            <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Socket</span>(<span class="hljs-string">&quot;127.0.0.1&quot;</span>, <span class="hljs-number">6666</span>);<br><br>            <span class="hljs-comment">// 2、从socket通信管道中得到一个字节输出流 负责发送数据</span><br>            <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> socket.getOutputStream();<br><br>            <span class="hljs-comment">// 3、把低级的字节流包装成打印流</span><br>            <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(os);<br><br>            <span class="hljs-type">Scanner</span> <span class="hljs-variable">sc</span> <span class="hljs-operator">=</span>  <span class="hljs-keyword">new</span> <span class="hljs-title class_">Scanner</span>(System.in);<br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                System.out.println(<span class="hljs-string">&quot;请说：&quot;</span>);<br>                <span class="hljs-type">String</span> <span class="hljs-variable">msg</span> <span class="hljs-operator">=</span> sc.nextLine();<br>                <span class="hljs-comment">// 4、发送消息</span><br>                ps.println(msg);<br>                ps.flush();<br>            &#125;<br>            <span class="hljs-comment">// 关闭资源。</span><br>            <span class="hljs-comment">// socket.close();</span><br><br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：实现服务端可以同时处理多个客户端的消息。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo2</span> &#123;<br><br>    <span class="hljs-comment">// 使用静态变量记住一个线程池对象</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">ExecutorService</span> <span class="hljs-variable">pool</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>(<span class="hljs-number">300</span>,<br>            <span class="hljs-number">1500</span>, <span class="hljs-number">6</span>, TimeUnit.SECONDS,<br>            <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayBlockingQueue</span>&lt;&gt;(<span class="hljs-number">2</span>)<br>    , Executors.defaultThreadFactory(), <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>.AbortPolicy());<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;===服务端启动成功===&quot;</span>);<br>            <span class="hljs-comment">// 1、注册端口</span><br>            <span class="hljs-type">ServerSocket</span> <span class="hljs-variable">serverSocket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerSocket</span>(<span class="hljs-number">6666</span>);<br>            <span class="hljs-comment">// a.定义一个死循环由主线程负责不断的接收客户端的Socket管道连接。</span><br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                <span class="hljs-comment">// 2、每接收到一个客户端的Socket管道，</span><br>                <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> serverSocket.accept();<br>                System.out.println(socket.getRemoteSocketAddress()+ <span class="hljs-string">&quot;它来了，上线了！&quot;</span>);<br><br>                <span class="hljs-comment">// 任务对象负责读取消息。</span><br>                <span class="hljs-type">Runnable</span> <span class="hljs-variable">target</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerReaderRunnable</span>(socket);<br>                pool.execute(target);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerReaderRunnable</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Runnable</span>&#123;<br>    <span class="hljs-keyword">private</span> Socket socket;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ServerReaderRunnable</span><span class="hljs-params">(Socket socket)</span>&#123;<br>        <span class="hljs-built_in">this</span>.socket = socket;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 3、从socket通信管道中得到一个字节输入流</span><br>            <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> socket.getInputStream();<br>            <span class="hljs-comment">// 4、把字节输入流包装成缓冲字符输入流进行消息的接收</span><br>            <span class="hljs-type">BufferedReader</span> <span class="hljs-variable">br</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedReader</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputStreamReader</span>(is));<br>            <span class="hljs-comment">// 5、按照行读取消息</span><br>            String msg;<br>            <span class="hljs-keyword">while</span> ((msg = br.readLine()) != <span class="hljs-literal">null</span>)&#123;<br>                System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;说了：: &quot;</span> + msg);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;下线了！！！&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="即时通信">即时通信</h6>
<p><strong>即时通信，是指一个客户端的消息发出去，其他客户端可以接收到。</strong></p>
<p><strong>之前我们的消息都是发给服务端的。</strong></p>
<p><strong>即时通信需要进行端口转发的设计思想。</strong></p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430093310743.png" srcset="/img/loading.gif" lazyload class="">
<p>1.即时通信是什么含义，要实现怎么样的设计？</p>
<p><strong>即时通信，是指一个客户端的消息发出去，其他客户端可以接收到</strong></p>
<p><strong>即时通信需要进行端口转发的设计思想。</strong></p>
<p><strong>服务端需要把在线的Socket管道存储起来</strong></p>
<p><strong>一旦收到一个消息要推送给其他管道</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    拓展：即时通信</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    客户端：发消息的同时，随时有人发消息过来。</span><br><span class="hljs-comment">    服务端：接收消息后，推送给其他所有的在线socket</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ClientDemo1</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;====客户端启动===&quot;</span>);<br>            <span class="hljs-comment">// 1、创建Socket通信管道请求有服务端的连接</span><br>            <span class="hljs-comment">// public Socket(String host, int port)</span><br>            <span class="hljs-comment">// 参数一：服务端的IP地址</span><br>            <span class="hljs-comment">// 参数二：服务端的端口</span><br>            <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Socket</span>(<span class="hljs-string">&quot;127.0.0.1&quot;</span>, <span class="hljs-number">6868</span>);<br><br>            <span class="hljs-comment">// 马上为客户端分配一个独立的线程负责读取它收到的消息</span><br>            <span class="hljs-keyword">new</span> <span class="hljs-title class_">ClientReaderThread</span>(socket).start();<br><br>            <span class="hljs-comment">// 2、从socket通信管道中得到一个字节输出流 负责发送数据</span><br>            <span class="hljs-type">OutputStream</span> <span class="hljs-variable">os</span> <span class="hljs-operator">=</span> socket.getOutputStream();<br><br>            <span class="hljs-comment">// 3、把低级的字节流包装成打印流</span><br>            <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(os);<br><br>            <span class="hljs-type">Scanner</span> <span class="hljs-variable">sc</span> <span class="hljs-operator">=</span>  <span class="hljs-keyword">new</span> <span class="hljs-title class_">Scanner</span>(System.in);<br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                System.out.println(<span class="hljs-string">&quot;请说：&quot;</span>);<br>                <span class="hljs-type">String</span> <span class="hljs-variable">msg</span> <span class="hljs-operator">=</span> sc.nextLine();<br>                <span class="hljs-comment">// 4、发送消息</span><br>                ps.println(msg);<br>                ps.flush();<br>            &#125;<br>            <span class="hljs-comment">// 关闭资源。</span><br>            <span class="hljs-comment">// socket.close();</span><br><br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ClientReaderThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span>&#123;<br>    <span class="hljs-keyword">private</span> Socket socket;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ClientReaderThread</span><span class="hljs-params">(Socket socket)</span>&#123;<br>        <span class="hljs-built_in">this</span>.socket = socket;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 3、从socket通信管道中得到一个字节输入流</span><br>            <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> socket.getInputStream();<br>            <span class="hljs-comment">// 4、把字节输入流包装成缓冲字符输入流进行消息的接收</span><br>            <span class="hljs-type">BufferedReader</span> <span class="hljs-variable">br</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedReader</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputStreamReader</span>(is));<br>            <span class="hljs-comment">// 5、按照行读取消息</span><br>            String msg;<br>            <span class="hljs-keyword">while</span> ((msg = br.readLine()) != <span class="hljs-literal">null</span>)&#123;<br>                System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;收到了: &quot;</span> + msg);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            System.out.println(<span class="hljs-string">&quot;服务端把你踢出去了~~&quot;</span>);<br>        &#125;<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标: 即时通信</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerDemo2</span> &#123;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> List&lt;Socket&gt; onLineSockets = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;===服务端启动成功===&quot;</span>);<br>            <span class="hljs-comment">// 1、注册端口</span><br>            <span class="hljs-type">ServerSocket</span> <span class="hljs-variable">serverSocket</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerSocket</span>(<span class="hljs-number">6868</span>);<br>            <span class="hljs-comment">// a.定义一个死循环由主线程负责不断的接收客户端的Socket管道连接。</span><br>            <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) &#123;<br>                <span class="hljs-comment">// 2、每接收到一个客户端的Socket管道，交给一个独立的子线程负责读取消息</span><br>                <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> serverSocket.accept();<br>                System.out.println(socket.getRemoteSocketAddress()+ <span class="hljs-string">&quot;它来了，上线了！&quot;</span>);<br>                <span class="hljs-comment">// 把当前客户端管道Socket加入到在线集合中去</span><br>                onLineSockets.add(socket);<br><br>                <span class="hljs-comment">// 3、开始创建独立线程处理socket</span><br>                <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerReaderThread</span>(socket).start();<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerReaderThread</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Thread</span>&#123;<br>    <span class="hljs-keyword">private</span> Socket socket;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ServerReaderThread</span><span class="hljs-params">(Socket socket)</span>&#123;<br>        <span class="hljs-built_in">this</span>.socket = socket;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 3、从socket通信管道中得到一个字节输入流</span><br>            <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> socket.getInputStream();<br>            <span class="hljs-comment">// 4、把字节输入流包装成缓冲字符输入流进行消息的接收</span><br>            <span class="hljs-type">BufferedReader</span> <span class="hljs-variable">br</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedReader</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">InputStreamReader</span>(is));<br>            <span class="hljs-comment">// 5、按照行读取消息</span><br>            String msg;<br>            <span class="hljs-keyword">while</span> ((msg = br.readLine()) != <span class="hljs-literal">null</span>)&#123;<br>                System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;说了：: &quot;</span> + msg);<br>                <span class="hljs-comment">// 把这个消息发给当前所有在线socket</span><br>                sendMsgToAll(msg);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;下线了！！！&quot;</span>);<br>            <span class="hljs-comment">// 从在线集合中抹掉本客户端socket</span><br>            ServerDemo2.onLineSockets.remove(socket);<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">sendMsgToAll</span><span class="hljs-params">(String msg)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 遍历全部的在线 socket给他们发消息</span><br>            <span class="hljs-keyword">for</span> (Socket onLineSocket : ServerDemo2.onLineSockets) &#123;<br>                <span class="hljs-comment">// 除了自己的socket，其他socket我都发！！</span><br>                <span class="hljs-keyword">if</span>(onLineSocket != socket)&#123;<br>                    <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(socket.getOutputStream());<br>                    ps.println(msg);<br>                    ps.flush();<br>                &#125;<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="bs开发">BS开发</h6>
<p><strong>HTTP响应数据的协议格式：就是给浏览器显示的网页信息</strong></p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430094241610.png" srcset="/img/loading.gif" lazyload class="">
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ServerReaderRunnable</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Runnable</span>&#123;<br>    <span class="hljs-keyword">private</span> Socket socket;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">ServerReaderRunnable</span><span class="hljs-params">(Socket socket)</span>&#123;<br>        <span class="hljs-built_in">this</span>.socket = socket;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 浏览器 已经与本线程建立了Socket管道</span><br>            <span class="hljs-comment">// 响应消息给浏览器显示</span><br>            <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(socket.getOutputStream());<br>            <span class="hljs-comment">// 必须响应HTTP协议格式数据，否则浏览器不认识消息</span><br>            ps.println(<span class="hljs-string">&quot;HTTP/1.1 200 OK&quot;</span>); <span class="hljs-comment">// 协议类型和版本 响应成功的消息！</span><br>            ps.println(<span class="hljs-string">&quot;Content-Type:text/html;charset=UTF-8&quot;</span>); <span class="hljs-comment">// 响应的数据类型：文本/网页</span><br><br>            ps.println(); <span class="hljs-comment">// 必须发送一个空行</span><br><br>            <span class="hljs-comment">// 才可以响应数据回去给浏览器</span><br>            ps.println(<span class="hljs-string">&quot;&lt;span style=&#x27;color:red;font-size:90px&#x27;&gt;《最牛的149期》 &lt;/span&gt;&quot;</span>);<br>            ps.close();<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            System.out.println(socket.getRemoteSocketAddress() + <span class="hljs-string">&quot;下线了！！！&quot;</span>);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs java">**<br>    了解：BS-浏览器-服务器基本了解。<br><br>    引入：<br>        之前客户端和服务端都需要自己开发。也就是CS架构。<br>        接下来模拟一下BS架构。<br><br>    客户端：浏览器。（无需开发）<br>    服务端：自己开发。<br>    需求：在浏览器中请求本程序，响应一个网页文字给浏览器显示<br><br><br> */<br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BSserverDemo</span> &#123;<br>    <span class="hljs-comment">// 使用静态变量记住一个线程池对象</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">ExecutorService</span> <span class="hljs-variable">pool</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>(<span class="hljs-number">3</span>,<br>            <span class="hljs-number">5</span>, <span class="hljs-number">6</span>, TimeUnit.SECONDS,<br>            <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayBlockingQueue</span>&lt;&gt;(<span class="hljs-number">2</span>)<br>            , Executors.defaultThreadFactory(), <span class="hljs-keyword">new</span> <span class="hljs-title class_">ThreadPoolExecutor</span>.AbortPolicy());<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            <span class="hljs-comment">// 1.注册端口</span><br>            <span class="hljs-type">ServerSocket</span> <span class="hljs-variable">ss</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerSocket</span>(<span class="hljs-number">8080</span>);<br>            <span class="hljs-comment">// 2.创建一个循环接收多个客户端的请求。</span><br>            <span class="hljs-keyword">while</span>(<span class="hljs-literal">true</span>)&#123;<br>                <span class="hljs-type">Socket</span> <span class="hljs-variable">socket</span> <span class="hljs-operator">=</span> ss.accept();<br>                <span class="hljs-comment">// 3.交给一个独立的线程来处理！</span><br>                pool.execute(<span class="hljs-keyword">new</span> <span class="hljs-title class_">ServerReaderRunnable</span>(socket));<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h4 id="单元测试反射注解动态管理">单元测试、反射、注解、动态管理</h4>
<h5 id="单元测试">单元测试</h5>
<ul>
<li>单元测试就是针对最小的功能单元编写测试代码，Java程序最小的功能单元是方法，因此，单元测试就是针对Java方法的测试，进而检查方法的正确性。</li>
</ul>
<p><strong>目前测试方法是怎么进行的，存在什么问题</strong></p>
<ul>
<li><p>只有一个main方法，如果一个方法的测试失败了，其他方法测试会受到影响。</p></li>
<li><p>无法得到测试的结果报告，需要程序员自己去观察测试是否成功。</p></li>
<li><p>无法实现自动化测试。</p></li>
</ul>
<h6 id="junit单元测试框架"><strong>Junit单元测试框架</strong></h6>
<ul>
<li><p>JUnit是使用Java语言实现的单元测试框架，它是开源的，Java开发者都应当学习并使用JUnit编写单元测试。</p></li>
<li><p>此外，几乎所有的IDE工具都集成了JUnit，这样我们就可以直接在IDE中编写并运行JUnit测试，JUnit目前最新版本是5。</p></li>
</ul>
<p><strong>JUnit优点</strong></p>
<ul>
<li><p>JUnit可以灵活的选择执行哪些测试方法，可以一键执行全部测试方法。</p></li>
<li><p>Junit可以生成全部方法的测试报告。</p></li>
<li><p>单元测试中的某个方法测试失败了，不会影响其他测试方法的测试。</p></li>
</ul>
<h6 id="单元测试快速入门">单元测试快速入门</h6>
<p>需求：使用单元测试进行业务方法预期结果、正确性测试的快速入门</p>
<p>分析：</p>
<p>①将JUnit的jar包导入到项目中</p>
<p>​ IDEA通常整合好了Junit框架，一般不需要导入。</p>
<p>​ 如果IDEA没有整合好，需要自己手工导入如下2个JUnit的jar包 到模块</p>
<p>②编写测试方法：该测试方法必须是公共的无参数无返回值的非静态方法。</p>
<p>③在测试方法上使用@Test注解：标注该方法是一个测试方法</p>
<p>④在测试方法中完成被测试方法的预期正确性测试。</p>
<p>⑤选中测试方法，选择“JUnit运行”
，如果测试良好则是绿色；如果测试失败，则是红色</p>
<p><strong>Junit常用注解(Junit 4.xxxx版本)</strong></p>
<table>
<colgroup>
<col style="width: 16%" />
<col style="width: 83%" />
</colgroup>
<thead>
<tr class="header">
<th>注解</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><span class="citation" data-cites="Test">@Test</span></td>
<td>测试方法</td>
</tr>
<tr class="even">
<td><span class="citation" data-cites="Before">@Before</span></td>
<td>用来修饰实例方法，该方法会在每一个测试方法执行之前执行一次。</td>
</tr>
<tr class="odd">
<td><span class="citation" data-cites="After">@After</span></td>
<td>用来修饰实例方法，该方法会在每一个测试方法执行之后执行一次。</td>
</tr>
<tr class="even">
<td><span class="citation"
data-cites="BeforeClass">@BeforeClass</span></td>
<td>用来静态修饰方法，该方法会在所有测试方法之前只执行一次。</td>
</tr>
<tr class="odd">
<td><span class="citation"
data-cites="AfterClass">@AfterClass</span></td>
<td>用来静态修饰方法，该方法会在所有测试方法之后只执行一次。</td>
</tr>
</tbody>
</table>
<p><strong>Junit常用注解(Junit 5.xxxx版本)</strong></p>
<table>
<colgroup>
<col style="width: 15%" />
<col style="width: 84%" />
</colgroup>
<thead>
<tr class="header">
<th>注解</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><span class="citation" data-cites="Test">@Test</span></td>
<td>测试方法</td>
</tr>
<tr class="even">
<td><span class="citation"
data-cites="BeforeEach">@BeforeEach</span></td>
<td>用来修饰实例方法，该方法会在每一个测试方法执行之前执行一次。</td>
</tr>
<tr class="odd">
<td><span class="citation" data-cites="AfterEach">@AfterEach</span></td>
<td>用来修饰实例方法，该方法会在每一个测试方法执行之后执行一次。</td>
</tr>
<tr class="even">
<td><span class="citation" data-cites="BeforeAll">@BeforeAll</span></td>
<td>用来静态修饰方法，该方法会在所有测试方法之前只执行一次。</td>
</tr>
<tr class="odd">
<td><span class="citation" data-cites="AfterAll">@AfterAll</span></td>
<td>用来静态修饰方法，该方法会在所有测试方法之后只执行一次。</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   业务方法</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">UserService</span> &#123;<br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">loginName</span><span class="hljs-params">(String loginName , String passWord)</span>&#123;<br>        <span class="hljs-keyword">if</span>(<span class="hljs-string">&quot;admin&quot;</span>.equals(loginName) &amp;&amp; <span class="hljs-string">&quot;123456&quot;</span>.equals(passWord))&#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;登录成功&quot;</span>;<br>        &#125;<span class="hljs-keyword">else</span> &#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;用户名或者密码有问题&quot;</span>;<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">selectNames</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-number">10</span>/<span class="hljs-number">2</span>);<br>        System.out.println(<span class="hljs-string">&quot;查询全部用户名称成功~~&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   测试类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TestUserService</span> &#123;<br><br>    <span class="hljs-comment">// 修饰实例方法的</span><br>    <span class="hljs-meta">@Before</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">before</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;===before方法执行一次===&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-meta">@After</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">after</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;===after方法执行一次===&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-comment">// 修饰静态方法</span><br>    <span class="hljs-meta">@BeforeClass</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">beforeClass</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;===beforeClass方法执行一次===&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-meta">@AfterClass</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">afterClass</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;===afterClass方法执行一次===&quot;</span>);<br>    &#125;<br><br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       测试方法</span><br><span class="hljs-comment">       注意点：</span><br><span class="hljs-comment">            1、必须是公开的，无参数 无返回值的方法</span><br><span class="hljs-comment">            2、测试方法必须使用<span class="hljs-doctag">@Test</span>注解标记。</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testLoginName</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-type">UserService</span> <span class="hljs-variable">userService</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">UserService</span>();<br>        <span class="hljs-type">String</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> userService.loginName(<span class="hljs-string">&quot;admin&quot;</span>,<span class="hljs-string">&quot;123456&quot;</span>);<br><br>        <span class="hljs-comment">// 进行预期结果的正确性测试：断言。</span><br>        Assert.assertEquals(<span class="hljs-string">&quot;您的登录业务可能出现问题&quot;</span>, <span class="hljs-string">&quot;登录成功&quot;</span>, rs );<br>    &#125;<br><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">testSelectNames</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-type">UserService</span> <span class="hljs-variable">userService</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">UserService</span>();<br>        userService.selectNames();<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>
<h5 id="反射">反射</h5>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430164907424.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="反射概述"><strong>反射概述</strong></h6>
<ul>
<li><p>反射是指对于任何一个Class类，在"运行的时候"都可以直接得到这个类全部成分。</p></li>
<li><p>在运行时,可以直接得到这个类的构造器对象：Constructor</p></li>
<li><p>在运行时,可以直接得到这个类的成员变量对象：Field</p></li>
<li><p>在运行时,可以直接得到这个类的成员方法对象：Method</p></li>
<li><p>这种运行时动态获取类信息以及动态调用类中成分的能力称为Java语言的反射机制。</p></li>
</ul>
<h6 id="反射的关键"><strong>反射的关键：</strong></h6>
<ul>
<li>反射的第一步都是先得到编译后的Class类对象，然后就可以得到Class的全部成分。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs java">HelloWorld.java -&gt; javac -&gt; HelloWorld.<span class="hljs-keyword">class</span><br><span class="hljs-title class_">Class</span> c = HelloWorld.class;<br></code></pre></td></tr></table></figure>
<h6 id="获取类的对象"><strong>获取类的对象</strong></h6>
<p><strong>方式一：Class c1 =</strong>
<strong>Class.forName(“全类名”);</strong></p>
<p><strong>方式二：Class c2 =</strong> <strong>类名.class</strong></p>
<p><strong>方式三：Class c3 =</strong>
<strong>对象.getClass();</strong></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs jV">/**<br>   目标：反射的第一步：获取Class对象<br> */<br>public class Test &#123;<br>    public static void main(String[] args) throws Exception &#123;<br>        // 1、Class类中的一个静态方法：forName(全限名：包名 + 类名)<br>        Class c = Class.forName(&quot;com.itheima.d2_reflect_class.Student&quot;);<br>        System.out.println(c); // Student.class<br><br>        // 2、类名.class<br>        Class c1 = Student.class;<br>        System.out.println(c1);<br><br>        // 3、对象.getClass() 获取对象对应类的Class对象。<br>        Student s = new Student();<br>        Class c2 = s.getClass();<br>        System.out.println(c2);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="使用反射技术获取构造器对象并使用"><strong>使用反射技术获取构造器对象并使用</strong></h6>
<ul>
<li><p>反射的第一步是先得到类对象，然后从类对象中获取类的成分对象。</p></li>
<li><p>Class类中用于获取构造器的方法</p></li>
</ul>
<table>
<colgroup>
<col style="width: 58%" />
<col style="width: 41%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Constructor&lt;?&gt;[] getConstructors()</td>
<td>返回所有构造器对象的数组（只能拿public的）</td>
</tr>
<tr class="even">
<td>Constructor&lt;?&gt;[] getDeclaredConstructors()</td>
<td>返回所有构造器对象的数组，存在就能拿到</td>
</tr>
<tr class="odd">
<td>Constructor<T> getConstructor(Class&lt;?&gt;... parameterTypes)</td>
<td>返回单个构造器对象（只能拿public的）</td>
</tr>
<tr class="even">
<td>Constructor<T> getDeclaredConstructor(Class&lt;?&gt;...
parameterTypes)</td>
<td>返回单个构造器对象，存在就能拿到</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Student</span> &#123;<br>    <span class="hljs-keyword">private</span> String name;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> age;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-title function_">Student</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;无参数构造器执行！&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Student</span><span class="hljs-params">(String name, <span class="hljs-type">int</span> age)</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;有参数构造器执行！&quot;</span>);<br>        <span class="hljs-built_in">this</span>.name = name;<br>        <span class="hljs-built_in">this</span>.age = age;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getName</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> name;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setName</span><span class="hljs-params">(String name)</span> &#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">getAge</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> age;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setAge</span><span class="hljs-params">(<span class="hljs-type">int</span> age)</span> &#123;<br>        <span class="hljs-built_in">this</span>.age = age;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">toString</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;Student&#123;&quot;</span> +<br>                <span class="hljs-string">&quot;name=&#x27;&quot;</span> + name + <span class="hljs-string">&#x27;\&#x27;&#x27;</span> +<br>                <span class="hljs-string">&quot;, age=&quot;</span> + age +<br>                <span class="hljs-string">&#x27;&#125;&#x27;</span>;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：反射_获取Constructor构造器对象.</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    反射的第一步是先得到Class类对象。（Class文件）</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    反射中Class类型获取构造器提供了很多的API:</span><br><span class="hljs-comment">         1. Constructor getConstructor(Class... parameterTypes)</span><br><span class="hljs-comment">            根据参数匹配获取某个构造器，只能拿public修饰的构造器，几乎不用！</span><br><span class="hljs-comment">         2. Constructor getDeclaredConstructor(Class... parameterTypes)</span><br><span class="hljs-comment">            根据参数匹配获取某个构造器，只要申明就可以定位，不关心权限修饰符，建议使用！</span><br><span class="hljs-comment">         3. Constructor[] getConstructors()</span><br><span class="hljs-comment">            获取所有的构造器，只能拿public修饰的构造器。几乎不用！！太弱了！</span><br><span class="hljs-comment">         4. Constructor[] getDeclaredConstructors()</span><br><span class="hljs-comment">            获取所有申明的构造器，只要你写我就能拿到，无所谓权限。建议使用！！</span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">        获取类的全部构造器对象： Constructor[] getDeclaredConstructors()</span><br><span class="hljs-comment">            -- 获取所有申明的构造器，只要你写我就能拿到，无所谓权限。建议使用！！</span><br><span class="hljs-comment">        获取类的某个构造器对象：Constructor getDeclaredConstructor(Class... parameterTypes)</span><br><span class="hljs-comment">            -- 根据参数匹配获取某个构造器，只要申明就可以定位，不关心权限修饰符，建议使用！</span><br><span class="hljs-comment"></span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TestStudent01</span> &#123;<br>    <span class="hljs-comment">// 1. getConstructors:</span><br>    <span class="hljs-comment">// 获取全部的构造器：只能获取public修饰的构造器。</span><br>    <span class="hljs-comment">// Constructor[] getConstructors()</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getConstructors</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-comment">// a.第一步：获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.提取类中的全部的构造器对象(这里只能拿public修饰)</span><br>        Constructor[] constructors = c.getConstructors();<br>        <span class="hljs-comment">// c.遍历构造器</span><br>        <span class="hljs-keyword">for</span> (Constructor constructor : constructors) &#123;<br>            System.out.println(constructor.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + constructor.getParameterCount());<br>        &#125;<br>    &#125;<br><br><br>    <span class="hljs-comment">// 2.getDeclaredConstructors():</span><br>    <span class="hljs-comment">// 获取全部的构造器：只要你敢写，这里就能拿到，无所谓权限是否可及。</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclaredConstructors</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-comment">// a.第一步：获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.提取类中的全部的构造器对象</span><br>        Constructor[] constructors = c.getDeclaredConstructors();<br>        <span class="hljs-comment">// c.遍历构造器</span><br>        <span class="hljs-keyword">for</span> (Constructor constructor : constructors) &#123;<br>            System.out.println(constructor.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + constructor.getParameterCount());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">// 3.getConstructor(Class... parameterTypes)</span><br>    <span class="hljs-comment">// 获取某个构造器：只能拿public修饰的某个构造器</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getConstructor</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a.第一步：获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.定位单个构造器对象 (按照参数定位无参数构造器 只能拿public修饰的某个构造器)</span><br>        <span class="hljs-type">Constructor</span> <span class="hljs-variable">cons</span> <span class="hljs-operator">=</span> c.getConstructor();<br>        System.out.println(cons.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + cons.getParameterCount());<br>    &#125;<br><br><br>    <span class="hljs-comment">// 4.getConstructor(Class... parameterTypes)</span><br>    <span class="hljs-comment">// 获取某个构造器：只要你敢写，这里就能拿到，无所谓权限是否可及。</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclaredConstructor</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a.第一步：获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.定位单个构造器对象 (按照参数定位无参数构造器)</span><br>        <span class="hljs-type">Constructor</span> <span class="hljs-variable">cons</span> <span class="hljs-operator">=</span> c.getDeclaredConstructor();<br>        System.out.println(cons.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + cons.getParameterCount());<br><br>        <span class="hljs-comment">// c.定位某个有参构造器</span><br>        <span class="hljs-type">Constructor</span> <span class="hljs-variable">cons1</span> <span class="hljs-operator">=</span> c.getDeclaredConstructor(String.class, <span class="hljs-type">int</span>.class);<br>        System.out.println(cons1.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + cons1.getParameterCount());<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="constructor类中用于创建对象的方法"><strong>Constructor类中用于创建对象的方法</strong></h6>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>符号</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>T newInstance(Object... initargs)</td>
<td>根据指定的构造器创建对象</td>
</tr>
<tr class="even">
<td>public void setAccessible(boolean flag)</td>
<td>设置为true,表示取消访问检查，进行暴力反射</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标: 反射_获取Constructor构造器然后通过这个构造器初始化对象。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    反射获取Class中的构造器对象Constructor作用：</span><br><span class="hljs-comment">            也是初始化并得到类的一个对象返回。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Constructor的API:</span><br><span class="hljs-comment">         1. T newInstance(Object... initargs)</span><br><span class="hljs-comment">                创建对象，注入构造器需要的数据。</span><br><span class="hljs-comment">         2. void setAccessible(true)</span><br><span class="hljs-comment">                修改访问权限，true代表暴力攻破权限，false表示保留不可访问权限(暴力反射)</span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">        可以通过定位类的构造器对象。</span><br><span class="hljs-comment">        如果构造器对象没有访问权限可以通过：void setAccessible(true)打开权限</span><br><span class="hljs-comment">        构造器可以通过T newInstance(Object... initargs)调用自己，传入参数！</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TestStudent02</span> &#123;<br>    <span class="hljs-comment">// 1.调用构造器得到一个类的对象返回。</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclaredConstructor</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a.第一步：获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.定位单个构造器对象 (按照参数定位无参数构造器)</span><br>        <span class="hljs-type">Constructor</span> <span class="hljs-variable">cons</span> <span class="hljs-operator">=</span> c.getDeclaredConstructor();<br>        System.out.println(cons.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + cons.getParameterCount());<br><br>        <span class="hljs-comment">// 如果遇到了私有的构造器，可以暴力反射</span><br>        cons.setAccessible(<span class="hljs-literal">true</span>); <span class="hljs-comment">// 权限被打开，被打开一次</span><br><br>        <span class="hljs-type">Student</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> (Student) cons.newInstance();<br>        System.out.println(s);<br><br>        System.out.println(<span class="hljs-string">&quot;-------------------&quot;</span>);<br><br>        <span class="hljs-comment">// c.定位某个有参构造器</span><br>        <span class="hljs-type">Constructor</span> <span class="hljs-variable">cons1</span> <span class="hljs-operator">=</span> c.getDeclaredConstructor(String.class, <span class="hljs-type">int</span>.class);<br>        System.out.println(cons1.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + cons1.getParameterCount());<br><br>        <span class="hljs-type">Student</span> <span class="hljs-variable">s1</span> <span class="hljs-operator">=</span> (Student) cons1.newInstance(<span class="hljs-string">&quot;孙悟空&quot;</span>, <span class="hljs-number">1000</span>);<br>        System.out.println(s1);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="使用反射技术获取成员变量对象并使用"><strong>使用反射技术获取成员变量对象并使用</strong></h6>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430170214454.png" srcset="/img/loading.gif" lazyload class="">
<ul>
<li><p>反射的第一步是先得到类对象，然后从类对象中获取类的成分对象。</p></li>
<li><p>Class类中用于获取成员变量的方法</p></li>
</ul>
<table>
<colgroup>
<col style="width: 45%" />
<col style="width: 54%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Field[] getFields()</td>
<td>返回所有成员变量对象的数组（只能拿public的）</td>
</tr>
<tr class="even">
<td>Field[] getDeclaredFields()</td>
<td>返回所有成员变量对象的数组，存在就能拿到</td>
</tr>
<tr class="odd">
<td>Field getField(String name)</td>
<td>返回单个成员变量对象（只能拿public的）</td>
</tr>
<tr class="even">
<td>Field getDeclaredField(String name)</td>
<td>返回单个成员变量对象，存在就能拿到</td>
</tr>
</tbody>
</table>
<p><strong>Field类中用于取值、赋值的方法</strong></p>
<table>
<thead>
<tr class="header">
<th>符号</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>void set(Object obj, Object value)：</td>
<td>赋值</td>
</tr>
<tr class="even">
<td>Object get(Object obj)</td>
<td>获取值。</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">     目标：反射_获取Field成员变量对象。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     反射的第一步是先得到Class类对象。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">     1、Field getField(String name);</span><br><span class="hljs-comment">            根据成员变量名获得对应Field对象，只能获得public修饰</span><br><span class="hljs-comment">     2.Field getDeclaredField(String name);</span><br><span class="hljs-comment">            根据成员变量名获得对应Field对象，只要申明了就可以得到</span><br><span class="hljs-comment">     3.Field[] getFields();</span><br><span class="hljs-comment">            获得所有的成员变量对应的Field对象，只能获得public的</span><br><span class="hljs-comment">     4.Field[] getDeclaredFields();</span><br><span class="hljs-comment">            获得所有的成员变量对应的Field对象，只要申明了就可以得到</span><br><span class="hljs-comment">     小结：</span><br><span class="hljs-comment">        获取全部成员变量：getDeclaredFields</span><br><span class="hljs-comment">        获取某个成员变量：getDeclaredField</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FieldDemo01</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 1.获取全部的成员变量。</span><br><span class="hljs-comment">     * Field[] getDeclaredFields();</span><br><span class="hljs-comment">     *  获得所有的成员变量对应的Field对象，只要申明了就可以得到</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclaredFields</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-comment">// a.定位Class对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.定位全部成员变量</span><br>        Field[] fields = c.getDeclaredFields();<br>        <span class="hljs-comment">// c.遍历一下</span><br>        <span class="hljs-keyword">for</span> (Field field : fields) &#123;<br>            System.out.println(field.getName() + <span class="hljs-string">&quot;==&gt;&quot;</span> + field.getType());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">        2.获取某个成员变量对象 Field getDeclaredField(String name);</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclaredField</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a.定位Class对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.根据名称定位某个成员变量</span><br>        <span class="hljs-type">Field</span> <span class="hljs-variable">f</span> <span class="hljs-operator">=</span> c.getDeclaredField(<span class="hljs-string">&quot;age&quot;</span>);<br>        System.out.println(f.getName() +<span class="hljs-string">&quot;===&gt;&quot;</span> + f.getType());<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：反射获取成员变量: 取值和赋值。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Field的方法：给成员变量赋值和取值</span><br><span class="hljs-comment">        void set(Object obj, Object value)：给对象注入某个成员变量数据</span><br><span class="hljs-comment">        Object get(Object obj):获取对象的成员变量的值。</span><br><span class="hljs-comment">        void setAccessible(true);暴力反射，设置为可以直接访问私有类型的属性。</span><br><span class="hljs-comment">        Class getType(); 获取属性的类型，返回Class对象。</span><br><span class="hljs-comment">        String getName(); 获取属性的名称。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FieldDemo02</span> &#123;<br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setField</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a.反射第一步，获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Student.class;<br>        <span class="hljs-comment">// b.提取某个成员变量</span><br>        <span class="hljs-type">Field</span> <span class="hljs-variable">ageF</span> <span class="hljs-operator">=</span> c.getDeclaredField(<span class="hljs-string">&quot;age&quot;</span>);<br><br>        ageF.setAccessible(<span class="hljs-literal">true</span>); <span class="hljs-comment">// 暴力打开权限</span><br><br>        <span class="hljs-comment">// c.赋值</span><br>        <span class="hljs-type">Student</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>();<br>        ageF.set(s , <span class="hljs-number">18</span>);  <span class="hljs-comment">// s.setAge(18);</span><br>        System.out.println(s);<br><br>        <span class="hljs-comment">// d、取值</span><br>        <span class="hljs-type">int</span> <span class="hljs-variable">age</span> <span class="hljs-operator">=</span> (<span class="hljs-type">int</span>) ageF.get(s);<br>        System.out.println(age);<br><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="使用反射技术获取方法对象并使用"><strong>使用反射技术获取方法对象并使用</strong></h6>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430171323459-165154597765923.png" srcset="/img/loading.gif" lazyload class="">
<table>
<colgroup>
<col style="width: 57%" />
<col style="width: 42%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Method[] getMethods()</td>
<td>返回所有成员方法对象的数组（只能拿public的）</td>
</tr>
<tr class="even">
<td>Method[] getDeclaredMethods()</td>
<td>返回所有成员方法对象的数组，存在就能拿到</td>
</tr>
<tr class="odd">
<td>Method getMethod(String name, Class&lt;?&gt;... parameterTypes)</td>
<td>返回单个成员方法对象（只能拿public的）</td>
</tr>
<tr class="even">
<td>Method getDeclaredMethod(String name, Class&lt;?&gt;...
parameterTypes)</td>
<td>返回单个成员方法对象，存在就能拿到</td>
</tr>
</tbody>
</table>
<p><strong>Method类中用于触发执行的方法</strong></p>
<table>
<colgroup>
<col style="width: 40%" />
<col style="width: 59%" />
</colgroup>
<thead>
<tr class="header">
<th>符号</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Object invoke(Object obj, Object... args)</td>
<td>运行方法 参数一：用obj对象调用该方法
参数二：调用方法的传递的参数（如果没有就不写）
返回值：方法的返回值（如果没有就不写）</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Dog</span> &#123;<br>    <span class="hljs-keyword">private</span> String name ;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Dog</span><span class="hljs-params">()</span>&#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Dog</span><span class="hljs-params">(String name)</span> &#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">run</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;狗跑的贼快~~&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">eat</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;狗吃骨头&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-keyword">private</span> String <span class="hljs-title function_">eat</span><span class="hljs-params">(String name)</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;狗吃&quot;</span> + name);<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;吃的很开心！&quot;</span>;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">inAddr</span><span class="hljs-params">()</span>&#123;<br>        System.out.println(<span class="hljs-string">&quot;在黑马学习Java!&quot;</span>);<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getName</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> name;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setName</span><span class="hljs-params">(String name)</span> &#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：反射——获取Method方法对象</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    反射获取类的Method方法对象：</span><br><span class="hljs-comment">         1、Method getMethod(String name,Class...args);</span><br><span class="hljs-comment">             根据方法名和参数类型获得对应的方法对象，只能获得public的</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">         2、Method getDeclaredMethod(String name,Class...args);</span><br><span class="hljs-comment">             根据方法名和参数类型获得对应的方法对象，包括private的</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">         3、Method[] getMethods();</span><br><span class="hljs-comment">             获得类中的所有成员方法对象，返回数组，只能获得public修饰的且包含父类的</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">         4、Method[] getDeclaredMethods();</span><br><span class="hljs-comment">            获得类中的所有成员方法对象，返回数组,只获得本类申明的方法。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    Method的方法执行：</span><br><span class="hljs-comment">        Object invoke(Object obj, Object... args)</span><br><span class="hljs-comment">          参数一：触发的是哪个对象的方法执行。</span><br><span class="hljs-comment">          参数二： args：调用方法时传递的实际参数</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MethodDemo01</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 1.获得类中的所有成员方法对象</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclaredMethods</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-comment">// a.获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Dog.class;<br>        <span class="hljs-comment">// b.提取全部方法；包括私有的</span><br>        Method[] methods = c.getDeclaredMethods();<br>        <span class="hljs-comment">// c.遍历全部方法</span><br>        <span class="hljs-keyword">for</span> (Method method : methods) &#123;<br>            System.out.println(method.getName() +<span class="hljs-string">&quot; 返回值类型：&quot;</span> + method.getReturnType() + <span class="hljs-string">&quot; 参数个数：&quot;</span> + method.getParameterCount());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     * 2. 获取某个方法对象</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">getDeclardMethod</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a.获取类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> Dog.class;<br>        <span class="hljs-comment">// b.提取单个方法对象</span><br>        <span class="hljs-type">Method</span> <span class="hljs-variable">m</span> <span class="hljs-operator">=</span> c.getDeclaredMethod(<span class="hljs-string">&quot;eat&quot;</span>);<br>        <span class="hljs-type">Method</span> <span class="hljs-variable">m2</span> <span class="hljs-operator">=</span> c.getDeclaredMethod(<span class="hljs-string">&quot;eat&quot;</span>, String.class);<br><br>        <span class="hljs-comment">// 暴力打开权限了</span><br>        m.setAccessible(<span class="hljs-literal">true</span>);<br>        m2.setAccessible(<span class="hljs-literal">true</span>);<br><br>        <span class="hljs-comment">// c.触发方法的执行</span><br>        <span class="hljs-type">Dog</span> <span class="hljs-variable">d</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Dog</span>();<br>        <span class="hljs-comment">// 注意：方法如果是没有结果回来的，那么返回的是null.</span><br>        <span class="hljs-type">Object</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> m.invoke(d);<br>        System.out.println(result);<br><br>        <span class="hljs-type">Object</span> <span class="hljs-variable">result2</span> <span class="hljs-operator">=</span> m2.invoke(d, <span class="hljs-string">&quot;骨头&quot;</span>);<br>        System.out.println(result2);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6
id="反射的作用绕过编译阶段为集合添加数据"><strong>反射的作用</strong>——绕过编译阶段为集合添加数据****</h6>
<ul>
<li>反射是作用在运行时的技术，此时集合的泛型将不能产生约束了，此时是可以为集合存入其他任意类型的元素的。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java">ArrayList&lt;Integer&gt; list = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>list.add(<span class="hljs-number">100</span>);<br><span class="hljs-comment">// list.add(“黑马&quot;); // 报错</span><br>list.add(<span class="hljs-number">99</span>);<br></code></pre></td></tr></table></figure>
<ul>
<li>泛型只是在编译阶段可以约束集合只能操作某种数据类型，在编译成Class文件进入运行阶段的时候，其真实类型都是ArrayList了，泛型相当于被擦除了。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ReflectDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 需求：反射实现泛型擦除后，加入其他类型的元素</span><br>        ArrayList&lt;String&gt; lists1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        ArrayList&lt;Integer&gt; lists2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br><br>        System.out.println(lists1.getClass());<br>        System.out.println(lists2.getClass());<br><br>        System.out.println(lists1.getClass() ==  lists2.getClass());  <span class="hljs-comment">// ArrayList.class</span><br><br>        System.out.println(<span class="hljs-string">&quot;---------------------------&quot;</span>);<br>        ArrayList&lt;Integer&gt; lists3 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        lists3.add(<span class="hljs-number">23</span>);<br>        lists3.add(<span class="hljs-number">22</span>);<br>        <span class="hljs-comment">// lists3.add(&quot;黑马&quot;);</span><br><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> lists3.getClass(); <span class="hljs-comment">// ArrayList.class  ===&gt; public boolean add(E e)</span><br>        <span class="hljs-comment">// 定位c类中的add方法</span><br>        <span class="hljs-type">Method</span> <span class="hljs-variable">add</span> <span class="hljs-operator">=</span> c.getDeclaredMethod(<span class="hljs-string">&quot;add&quot;</span>, Object.class);<br>        <span class="hljs-type">boolean</span> <span class="hljs-variable">rs</span> <span class="hljs-operator">=</span> (<span class="hljs-type">boolean</span>) add.invoke(lists3, <span class="hljs-string">&quot;黑马&quot;</span>);<br>        System.out.println(rs);<br><br>        System.out.println(lists3);<br><span class="hljs-comment">//也可以这样</span><br>        <span class="hljs-type">ArrayList</span> <span class="hljs-variable">list4</span> <span class="hljs-operator">=</span> lists3;<br>        list4.add(<span class="hljs-string">&quot;白马&quot;</span>);<br>        list4.add(<span class="hljs-literal">false</span>);<br>        System.out.println(lists3);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="反射做通用框架">反射做通用框架</h6>
<p>给你任意一个对象，在不清楚对象字段的情况可以，可以把对象的字段名称和对应值存储到文件中去。</p>
<p><strong>分析</strong></p>
<p>①定义一个方法，可以接收任意类的对象。</p>
<p>②每次收到一个对象后，需要解析这个对象的全部成员变量名称。</p>
<p>③这个对象可能是任意的，那么怎么样才可以知道这个对象的全部成员变量名称呢？</p>
<p>④使用反射获取对象的Class类对象，然后获取全部成员变量信息。</p>
<p>⑤遍历成员变量信息，然后提取本成员变量在对象中的具体值</p>
<p>⑥存入成员变量名称和值到文件中去即可。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：提供一个通用框架，支持保存所有对象的具体信息。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ReflectDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-type">Student</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Student</span>();<br>        s.setName(<span class="hljs-string">&quot;猪八戒&quot;</span>);<br>        s.setClassName(<span class="hljs-string">&quot;西天跑路1班&quot;</span>);<br>        s.setAge(<span class="hljs-number">1000</span>);<br>        s.setHobby(<span class="hljs-string">&quot;吃，睡&quot;</span>);<br>        s.setSex(<span class="hljs-string">&#x27;男&#x27;</span>);<br>        MybatisUtil.save(s);<br><br>        <span class="hljs-type">Teacher</span> <span class="hljs-variable">t</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Teacher</span>();<br>        t.setName(<span class="hljs-string">&quot;波仔&quot;</span>);<br>        t.setSex(<span class="hljs-string">&#x27;男&#x27;</span>);<br>        t.setSalary(<span class="hljs-number">6000</span>);<br>        MybatisUtil.save(t);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MybatisUtil</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     保存任意类型的对象</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> obj</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">save</span><span class="hljs-params">(Object obj)</span>&#123;<br>        <span class="hljs-keyword">try</span> (<br>                <span class="hljs-type">PrintStream</span> <span class="hljs-variable">ps</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PrintStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">&quot;junit-reflect-annotation-proxy-app/src/data.txt&quot;</span>, <span class="hljs-literal">true</span>));<br>        )&#123;<br>            <span class="hljs-comment">// 1、提取这个对象的全部成员变量：只有反射可以解决</span><br>            <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> obj.getClass();  <span class="hljs-comment">//   c.getSimpleName()获取当前类名   c.getName获取全限名：包名+类名</span><br>            ps.println(<span class="hljs-string">&quot;================&quot;</span> + c.getSimpleName() + <span class="hljs-string">&quot;================&quot;</span>);<br><br>            <span class="hljs-comment">// 2、提取它的全部成员变量</span><br>            Field[] fields = c.getDeclaredFields();<br>            <span class="hljs-comment">// 3、获取成员变量的信息</span><br>            <span class="hljs-keyword">for</span> (Field field : fields) &#123;<br>                <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> field.getName();<br>                <span class="hljs-comment">// 提取本成员变量在obj对象中的值（取值）</span><br>                field.setAccessible(<span class="hljs-literal">true</span>);<br>                <span class="hljs-type">String</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> field.get(obj) + <span class="hljs-string">&quot;&quot;</span>;<br>                ps.println(name  + <span class="hljs-string">&quot;=&quot;</span> + value);<br>            &#125;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="注解概述作用"><strong>注解概述、作用</strong></h6>
<ul>
<li><p>Java 注解（Annotation）又称 Java 标注，是 JDK5.0
引入的一种注释机制。</p></li>
<li><p>Java
语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注。</p></li>
</ul>
<p><strong>注解的作用是什么呢？</strong></p>
<ul>
<li><p>对Java中类、方法、成员变量做标记，然后进行特殊处理，至于到底做何种处理由业务需求来决定。</p></li>
<li><p>例如：JUnit框架中，标记了注解@Test的方法就可以被当成测试方法执行，而没有标记的就不能当成测试方法执行。</p></li>
</ul>
<p><strong>自定义注解</strong> <strong>---</strong>
<strong>格式</strong></p>
<p>自定义注解就是自己做一个注解来使用。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> 注解名称 &#123;<br>	<span class="hljs-keyword">public</span> 属性类型 属性名() <span class="hljs-keyword">default</span> 默认值 ;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> MyBook &#123;<br>    String <span class="hljs-title function_">name</span><span class="hljs-params">()</span>;<br>    String[] authors();<br>    <span class="hljs-type">double</span> <span class="hljs-title function_">price</span><span class="hljs-params">()</span>;<br>&#125;<br><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：学会自定义注解。掌握其定义格式和语法。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-meta">@MyBook(name=&quot;《精通JavaSE》&quot;,authors = &#123;&quot;黑马&quot;, &quot;dlei&quot;&#125; , price = 199.5)</span><br><span class="hljs-comment">//@Book(value = &quot;/delete&quot;)</span><br><span class="hljs-comment">// @Book(&quot;/delete&quot;)</span><br><span class="hljs-meta">@Book(value = &quot;/delete&quot;, price = 23.5)</span><br><span class="hljs-comment">//@Book(&quot;/delete&quot;)</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">AnnotationDemo1</span> &#123;<br><br>    <span class="hljs-meta">@MyBook(name=&quot;《精通JavaSE2》&quot;,authors = &#123;&quot;黑马&quot;, &quot;dlei&quot;&#125; , price = 199.5)</span><br>    <span class="hljs-keyword">private</span> <span class="hljs-title function_">AnnotationDemo1</span><span class="hljs-params">()</span>&#123;<br><br>    &#125;<br><br>    <span class="hljs-meta">@MyBook(name=&quot;《精通JavaSE1》&quot;,authors = &#123;&quot;黑马&quot;, &quot;dlei&quot;&#125; , price = 199.5)</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-meta">@MyBook(name=&quot;《精通JavaSE2》&quot;,authors = &#123;&quot;黑马&quot;, &quot;dlei&quot;&#125; , price = 199.5)</span><br>        <span class="hljs-type">int</span> <span class="hljs-variable">age</span> <span class="hljs-operator">=</span> <span class="hljs-number">21</span>;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>特殊属性</strong></p>
<ul>
<li><p>value属性，如果只有一个value属性的情况下，使用value属性的时候可以省略value名称不写!!</p></li>
<li><p>但是如果有多个属性,
且多个属性没有默认值，那么value名称是不能省略的。</p></li>
</ul>
<h6 id="元注解">元注解</h6>
<ul>
<li>元注解：就是注解注解的注解。</li>
</ul>
<p><strong>元注解有两个：</strong></p>
<ul>
<li><p><strong><span class="citation"
data-cites="Target">@Target</span></strong>:
约束自定义注解只能在哪些地方使用，</p></li>
<li><p><strong><span class="citation"
data-cites="Retention">@Retention</span></strong>：申明注解的生命周期</p></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Target(&#123;ElementType.METHOD,ElementType.FIELD&#125;)</span> <span class="hljs-comment">// 元注解</span><br><span class="hljs-meta">@Retention(RetentionPolicy.RUNTIME)</span> <span class="hljs-comment">// 一直活着，在运行阶段这个注解也不消失</span><br><span class="hljs-keyword">public</span> <span class="hljs-meta">@interface</span> MyTest &#123;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><span class="citation"
data-cites="Target中可使用的值定义在ElementType枚举类中">@Target中可使用的值定义在ElementType枚举类中</span>，常用值如下</p>
<ul>
<li><p>TYPE，类，接口</p></li>
<li><p>FIELD, 成员变量</p></li>
<li><p>METHOD, 成员方法</p></li>
<li><p>PARAMETER, 方法参数</p></li>
<li><p>CONSTRUCTOR, 构造器</p></li>
<li><p>LOCAL_VARIABLE, 局部变量</p></li>
</ul>
<p><span class="citation"
data-cites="Retention中可使用的值定义在RetentionPolicy枚举类中">@Retention中可使用的值定义在RetentionPolicy枚举类中</span>，常用值如下</p>
<ul>
<li><p>SOURCE： 注解只作用在源码阶段，生成的字节码文件中不存在</p></li>
<li><p>CLASS：
注解作用在源码阶段，字节码文件阶段，运行阶段不存在，默认值.</p></li>
<li><p>RUNTIME：注解作用在源码阶段，字节码文件阶段，运行阶段（开发常用）</p></li>
</ul>
<h6 id="注解的解析"><strong>注解的解析</strong></h6>
<ul>
<li>注解的操作中经常需要进行解析，注解的解析就是判断是否存在注解，存在注解就解析出内容。</li>
</ul>
<p><strong>与注解解析相关的接口</strong></p>
<ul>
<li><p>Annotation: 注解的顶级接口，注解都是Annotation类型的对象</p></li>
<li><p>AnnotatedElement:该接口定义了与注解解析相关的解析方法</p></li>
</ul>
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr class="header">
<th>方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Annotation[] getDeclaredAnnotations()</td>
<td>获得当前对象上使用的所有注解，返回注解数组。</td>
</tr>
<tr class="even">
<td>T getDeclaredAnnotation(Class<T> annotationClass)</td>
<td>根据注解类型获得对应注解对象</td>
</tr>
<tr class="odd">
<td>boolean isAnnotationPresent(Class<Annotation> annotationClass)</td>
<td>判断当前对象是否使用了指定的注解，如果使用了则返回true，否则false</td>
</tr>
</tbody>
</table>
<p>所有的类成分Class, Method , Field ,
Constructor，都实现了AnnotatedElement接口他们都拥有解析注解的能力</p>
<p><strong>解析注解的技巧</strong></p>
<ul>
<li><p>注解在哪个成分上，我们就先拿哪个成分对象。</p></li>
<li><p>比如注解作用成员方法，则要获得该成员方法对应的Method对象，再来拿上面的注解</p></li>
<li><p>比如注解作用在类上，则要该类的Class对象，再来拿上面的注解</p></li>
<li><p>比如注解作用在成员变量上，则要获得该成员变量对应的Field对象，再来拿上面的注解</p></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：完成注解的解析</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">AnnotationDemo3</span> &#123;<br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parseClass</span><span class="hljs-params">()</span>&#123;<br>        <span class="hljs-comment">// a.先得到类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> BookStore.class;<br>        <span class="hljs-comment">// b.判断这个类上面是否存在这个注解</span><br>        <span class="hljs-keyword">if</span>(c.isAnnotationPresent(Bookk.class))&#123;<br>            <span class="hljs-comment">//c.直接获取该注解对象</span><br>            <span class="hljs-type">Bookk</span> <span class="hljs-variable">book</span> <span class="hljs-operator">=</span> (Bookk) c.getDeclaredAnnotation(Bookk.class);<br>            System.out.println(book.value());<br>            System.out.println(book.price());<br>            System.out.println(Arrays.toString(book.author()));<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parseMethod</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> NoSuchMethodException &#123;<br>        <span class="hljs-comment">// a.先得到类对象</span><br>        <span class="hljs-type">Class</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> BookStore.class;<br><br>        <span class="hljs-type">Method</span> <span class="hljs-variable">m</span> <span class="hljs-operator">=</span> c.getDeclaredMethod(<span class="hljs-string">&quot;test&quot;</span>);<br><br>        <span class="hljs-comment">// b.判断这个类上面是否存在这个注解</span><br>        <span class="hljs-keyword">if</span>(m.isAnnotationPresent(Bookk.class))&#123;<br>            <span class="hljs-comment">//c.直接获取该注解对象</span><br>            <span class="hljs-type">Bookk</span> <span class="hljs-variable">book</span> <span class="hljs-operator">=</span> (Bookk) m.getDeclaredAnnotation(Bookk.class);<br>            System.out.println(book.value());<br>            System.out.println(book.price());<br>            System.out.println(Arrays.toString(book.author()));<br>        &#125;<br>    &#125;<br>&#125;<br><br><span class="hljs-meta">@Bookk(value = &quot;《情深深雨濛濛》&quot;, price = 99.9, author = &#123;&quot;琼瑶&quot;, &quot;dlei&quot;&#125;)</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">BookStore</span>&#123;<br><br>    <span class="hljs-meta">@Bookk(value = &quot;《三少爷的剑》&quot;, price = 399.9, author = &#123;&quot;古龙&quot;, &quot;熊耀华&quot;&#125;)</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">test</span><span class="hljs-params">()</span>&#123;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h5 id="动态代理">动态代理</h5>
<h6 id="案例">案例</h6>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   模拟用户业务功能</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">UserService</span> &#123;<br>    String <span class="hljs-title function_">login</span><span class="hljs-params">(String loginName , String passWord)</span> ;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">selectUsers</span><span class="hljs-params">()</span>;<br>    <span class="hljs-type">boolean</span> <span class="hljs-title function_">deleteUsers</span><span class="hljs-params">()</span>;<br>    <span class="hljs-keyword">void</span> <span class="hljs-title function_">updateUsers</span><span class="hljs-params">()</span>;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">UserServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">UserService</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">login</span><span class="hljs-params">(String loginName, String passWord)</span>  &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            Thread.sleep(<span class="hljs-number">1000</span>);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>        <span class="hljs-keyword">if</span>(<span class="hljs-string">&quot;admin&quot;</span>.equals(loginName) &amp;&amp; <span class="hljs-string">&quot;1234&quot;</span>.equals(passWord)) &#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;success&quot;</span>;<br>        &#125;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;登录名和密码可能有毛病&quot;</span>;<br><br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">selectUsers</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;查询了100个用户数据！&quot;</span>);<br>        <span class="hljs-keyword">try</span> &#123;<br>            Thread.sleep(<span class="hljs-number">2000</span>);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">deleteUsers</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;删除100个用户数据！&quot;</span>);<br>            Thread.sleep(<span class="hljs-number">500</span>);<br>            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">updateUsers</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">try</span> &#123;<br>            System.out.println(<span class="hljs-string">&quot;修改100个用户数据！&quot;</span>);<br>            Thread.sleep(<span class="hljs-number">2500</span>);<br>        &#125; <span class="hljs-keyword">catch</span> (Exception e) &#123;<br>            e.printStackTrace();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Test</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-comment">// 1、把业务对象，直接做成一个代理对象返回，代理对象的类型也是 UserService类型</span><br>        <span class="hljs-type">UserService</span> <span class="hljs-variable">userService</span> <span class="hljs-operator">=</span> ProxyUtil.getProxy(<span class="hljs-keyword">new</span> <span class="hljs-title class_">UserServiceImpl</span>());<br>        System.out.println(userService.login(<span class="hljs-string">&quot;admin&quot;</span>, <span class="hljs-string">&quot;1234&quot;</span>));<br>        System.out.println(userService.deleteUsers());<br>        userService.selectUsers();<br>        userService.updateUsers(); <span class="hljs-comment">// 走代理</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    public static Object newProxyInstance(ClassLoader loader,  Class&lt;?&gt;[] interfaces, InvocationHandler h)</span><br><span class="hljs-comment">    参数一：类加载器，负责加载代理类到内存中使用。</span><br><span class="hljs-comment">    参数二：获取被代理对象实现的全部接口。代理要为全部接口的全部方法进行代理</span><br><span class="hljs-comment">    参数三：代理的核心处理逻辑</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ProxyUtil</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">      生成业务对象的代理对象。</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@param</span> obj</span><br><span class="hljs-comment">     * <span class="hljs-doctag">@return</span></span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; T  <span class="hljs-title function_">getProxy</span><span class="hljs-params">(T obj)</span> &#123;<br>        <span class="hljs-comment">// 返回了一个代理对象了</span><br>        <span class="hljs-keyword">return</span> (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(),<br>                obj.getClass().getInterfaces(),<br>                <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvocationHandler</span>() &#123;<br>                    <span class="hljs-meta">@Override</span><br>                    <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">invoke</span><span class="hljs-params">(Object proxy, Method method, Object[] args)</span> <span class="hljs-keyword">throws</span> Throwable &#123;<br>                        <span class="hljs-comment">// 参数一：代理对象本身。一般不管</span><br>                        <span class="hljs-comment">// 参数二：正在被代理的方法</span><br>                        <span class="hljs-comment">// 参数三：被代理方法，应该传入的参数</span><br>                       <span class="hljs-type">long</span> <span class="hljs-variable">startTimer</span> <span class="hljs-operator">=</span> System .currentTimeMillis();<br>                        <span class="hljs-comment">// 马上触发方法的真正执行。(触发真正的业务功能)</span><br>                        <span class="hljs-type">Object</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> method.invoke(obj, args);<br><br>                        <span class="hljs-type">long</span> <span class="hljs-variable">endTimer</span> <span class="hljs-operator">=</span> System.currentTimeMillis();<br>                        System.out.println(method.getName() + <span class="hljs-string">&quot;方法耗时：&quot;</span> + (endTimer - startTimer) / <span class="hljs-number">1000.0</span> + <span class="hljs-string">&quot;s&quot;</span>);<br><br>                        <span class="hljs-comment">// 把业务功能方法执行的结果返回给调用者</span><br>                        <span class="hljs-keyword">return</span> result;<br>                    &#125;<br>                &#125;);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p><strong>业务对象的的每个方法都要进行性能统计，存在大量重复的代码</strong>。</p>
<h6 id="动态代理-1">动态代理</h6>
<ul>
<li>代理就是被代理者没有能力或者不愿意去完成某件事情，需要找个人代替自己去完成这件事，动态代理就是用来对业务功能（方法）进行代理的。</li>
</ul>
<p>关键步骤</p>
<p>1.必须有接口，实现类要实现接口（代理通常是基于接口实现的）。</p>
<p>3.创建一个实现类的对象，该对象为业务对象，紧接着为业务对象做一个代理对象。</p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220430192519797-165154600613126.png" srcset="/img/loading.gif" lazyload class="">
<p><strong>动态代理的优点</strong></p>
<ul>
<li><p>非常的灵活，支持任意接口类型的实现类对象做代理，也可以直接为接本身做代理。</p></li>
<li><p>可以为被代理对象的所有方法做代理。</p></li>
<li><p>可以在不改变方法源码的情况下，实现对方法功能的增强。</p></li>
<li><p>不仅简化了编程工作、提高了软件系统的可扩展性，同时也提高了开发效率。</p></li>
</ul>
<h4 id="xml">XML</h4>
<p>XML是可扩展标记语言（eXtensible Markup
Language）的缩写，它是是一种数据表示格式，可以描述非常复杂的数据结构，常用于传输和存储数据。</p>
<h6
id="xml的几个特点和使用场景"><strong>XML的几个特点和使用场景</strong></h6>
<p>一是纯文本，默认使用UTF-8编码；二是可嵌套；</p>
<p>l如果把XML内容存为文件，那么它就是一个XML文件。</p>
<p>XML的使用场景：XML内容经常被当成消息进行网络传输，或者作为配置文件用于存储系统的信息。</p>
<h6 id="xml的创建"><strong>XML的创建</strong></h6>
<p><strong>IDEA创建XML文件的操作步骤</strong></p>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220501180353162-165154601918229.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="xml的标签元素规则"><strong>XML的标签(元素)规则</strong></h6>
<p>XML的标签(元素)规则</p>
<p>标签由一对尖括号和合法标识符组成:
<name></name>，必须存在一个根标签，有且只能有一个。</p>
<p>标签必须成对出现，有开始，有结束: <name></name></p>
<p>特殊的标签可以不成对，但是必须有结束标记，如:<br/></p>
<p>标签中可以定义属性，属性和标签名空格隔开,属性值必须用引号引起来<student id = “1"></name></p>
<p>标签需要正确的嵌套</p>
<h6 id="xml的其他组成"><strong>XML的其他组成</strong></h6>
<p>XML文件中可以定义注释信息：<!-- 注释内容 --></p>
<p>XML文件中可以存在以下特殊字符</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs java">&amp;lt;    &lt;  小于<br>&amp;gt;    &gt;  大于<br>&amp;amp;   &amp;  和号<br>&amp;apos;  <span class="hljs-string">&#x27;  单引号</span><br><span class="hljs-string">&amp;quot;  &quot;  引号</span><br></code></pre></td></tr></table></figure>
<p>XML文件中可以存在CDATA区: &lt;[CDATA[ …内容… ]]&gt;</p>
<p><strong>由于XML文件可以自定义标签，导致XML文件可以随意定义，程序在解析的时候可能出现问题。</strong></p>
<h6 id="什么是文档约束"><strong>什么是文档约束？</strong></h6>
<p>文档约束：是用来限定xml文件中的标签以及属性应该怎么写。</p>
<p>以此强制约束程序员必须按照文档约束的规定来编写xml文件。</p>
<h6 id="文档约束的分类"><strong>文档约束的分类</strong></h6>
<h6 id="dtd">DTD</h6>
<p>schema</p>
<p><strong>需求：</strong>利用DTD文档约束，约束一个XML文件的编写。</p>
<p><strong>分析：</strong></p>
<p>①：编写DTD约束文档，后缀必须是.dtd</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs xml-dtd">&lt;!ELEMENT 书架 (书+)&gt;<br>&lt;!ELEMENT 书 (书名,作者,售价)&gt;<br>&lt;!ELEMENT 书名 (#PCDATA)&gt;<br>&lt;!ELEMENT 作者 (#PCDATA)&gt;<br>&lt;!ELEMENT 售价 (#PCDATA)&gt;<br></code></pre></td></tr></table></figure>
<p>②：在需要编写的XML文件中导入该DTD约束文档</p>
<p>③：按照约束的规定编写XML文件的内容。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">&quot;1.0&quot;</span> encoding=<span class="hljs-string">&quot;UTF-8&quot;</span> ?&gt;</span><br><span class="hljs-meta">&lt;!DOCTYPE 书架 <span class="hljs-keyword">SYSTEM</span> <span class="hljs-string">&quot;data.dtd&quot;</span>&gt;</span><br>&lt;书架&gt;<br>    &lt;书&gt;<br>        &lt;书名&gt;精通JavaSE加强&lt;/书名&gt;<br>        &lt;作者&gt;dlei&lt;/作者&gt;<br>        &lt;售价&gt;很贵&lt;/售价&gt;<br>    &lt;/书&gt;<br>    &lt;书&gt;<br>        &lt;书名&gt;&lt;/书名&gt;<br>        &lt;作者&gt;&lt;/作者&gt;<br>        &lt;售价&gt;&lt;/售价&gt;<br>    &lt;/书&gt;<br>    &lt;书&gt;<br>        &lt;书名&gt;&lt;/书名&gt;<br>        &lt;作者&gt;&lt;/作者&gt;<br>        &lt;售价&gt;&lt;/售价&gt;<br>    &lt;/书&gt;<br>&lt;/书架&gt;<br></code></pre></td></tr></table></figure>
<h6 id="文档约束-schema"><strong>文档约束-schema</strong></h6>
<p>schema可以约束具体的数据类型，约束能力上更强大。</p>
<p>schema本身也是一个xml文件，本身也受到其他约束文件的要求，所以编写的更加严谨</p>
<p>1.XML的文档约束-schema的优点？</p>
<p>可以约束XML文件的标签内容格式，以及具体的数据类型。</p>
<p>本身也是xml文件，格式更严谨。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">&quot;1.0&quot;</span> encoding=<span class="hljs-string">&quot;UTF-8&quot;</span> ?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">schema</span> <span class="hljs-attr">xmlns</span>=<span class="hljs-string">&quot;http://www.w3.org/2001/XMLSchema&quot;</span></span><br><span class="hljs-tag">        <span class="hljs-attr">targetNamespace</span>=<span class="hljs-string">&quot;http://www.itcast.cn&quot;</span></span><br><span class="hljs-tag">        <span class="hljs-attr">elementFormDefault</span>=<span class="hljs-string">&quot;qualified&quot;</span> &gt;</span><br>    <span class="hljs-comment">&lt;!-- targetNamespace:申明约束文档的地址（命名空间）--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">element</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&#x27;书架&#x27;</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 写子元素 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">complexType</span>&gt;</span><br>            <span class="hljs-comment">&lt;!-- maxOccurs=&#x27;unbounded&#x27;: 书架下的子元素可以有任意多个！--&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">sequence</span> <span class="hljs-attr">maxOccurs</span>=<span class="hljs-string">&#x27;unbounded&#x27;</span>&gt;</span><br>                <span class="hljs-tag">&lt;<span class="hljs-name">element</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&#x27;书&#x27;</span>&gt;</span><br>                    <span class="hljs-comment">&lt;!-- 写子元素 --&gt;</span><br>                    <span class="hljs-tag">&lt;<span class="hljs-name">complexType</span>&gt;</span><br>                        <span class="hljs-tag">&lt;<span class="hljs-name">sequence</span>&gt;</span><br>                            <span class="hljs-tag">&lt;<span class="hljs-name">element</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&#x27;书名&#x27;</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&#x27;string&#x27;</span>/&gt;</span><br>                            <span class="hljs-tag">&lt;<span class="hljs-name">element</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&#x27;作者&#x27;</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&#x27;string&#x27;</span>/&gt;</span><br>                            <span class="hljs-tag">&lt;<span class="hljs-name">element</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&#x27;售价&#x27;</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&#x27;double&#x27;</span>/&gt;</span><br>                        <span class="hljs-tag">&lt;/<span class="hljs-name">sequence</span>&gt;</span><br>                    <span class="hljs-tag">&lt;/<span class="hljs-name">complexType</span>&gt;</span><br>                <span class="hljs-tag">&lt;/<span class="hljs-name">element</span>&gt;</span><br>            <span class="hljs-tag">&lt;/<span class="hljs-name">sequence</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">complexType</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">element</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">schema</span>&gt;</span><br></code></pre></td></tr></table></figure>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">&quot;1.0&quot;</span> encoding=<span class="hljs-string">&quot;UTF-8&quot;</span> ?&gt;</span><br>&lt;书架 xmlns=&quot;http://www.itcast.cn&quot;<br>    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;<br>    xsi:schemaLocation=&quot;http://www.itcast.cn data.xsd&quot;&gt;<br>    <span class="hljs-comment">&lt;!-- xmlns=&quot;http://www.itcast.cn&quot;  基本位置</span><br><span class="hljs-comment">         xsi:schemaLocation=&quot;http://www.itcast.cn books02.xsd&quot; 具体的位置 --&gt;</span><br>    &lt;书&gt;<br>        &lt;书名&gt;神雕侠侣&lt;/书名&gt;<br>        &lt;作者&gt;金庸&lt;/作者&gt;<br>        &lt;售价&gt;399.9&lt;/售价&gt;<br>    &lt;/书&gt;<br>    &lt;书&gt;<br>        &lt;书名&gt;神雕侠侣&lt;/书名&gt;<br>        &lt;作者&gt;金庸&lt;/作者&gt;<br>        &lt;售价&gt;19.5&lt;/售价&gt;<br>    &lt;/书&gt;<br><br>&lt;/书架&gt;<br></code></pre></td></tr></table></figure>
<h6 id="xml解析"><strong>XML解析</strong></h6>
<p>使用程序读取XML中的数据</p>
<p><strong>两种解析方式</strong></p>
<p>SAX解析//一行一行</p>
<p>DOM解析//整个文档解析</p>
<p><strong>Dom常见的解析工具</strong></p>
<table>
<colgroup>
<col style="width: 7%" />
<col style="width: 92%" />
</colgroup>
<thead>
<tr class="header">
<th>名称</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>JAXP</td>
<td>SUN公司提供的一套XML的解析的API</td>
</tr>
<tr class="even">
<td>JDOM</td>
<td>JDOM是一个开源项目，它基于树型结构，利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。</td>
</tr>
<tr class="odd">
<td>dom4j</td>
<td>是JDOM的升级品，用来读写XML文件的。具有性能优异、功能强大和极其易使用的特点，它的性能超过sun公司官方的dom
技术，同时它也是一个开放源代码的软件，Hibernate也用它来读写配置文件。</td>
</tr>
<tr class="even">
<td>jsoup</td>
<td>功能强大DOM方式的XML解析开发包，尤其对HTML解析更加方便</td>
</tr>
</tbody>
</table>
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220501182543306-165154603584732.png" srcset="/img/loading.gif" lazyload class="">
<img src="/2022/05/05/JAVA%E5%9F%BA%E7%A1%80/image-20220501182605641-165154605152335.png" srcset="/img/loading.gif" lazyload class="">
<h6 id="使用dom4j解析出xml文件">使用Dom4J解析出XML文件</h6>
<p><strong>需求：</strong>使用Dom4J把一个XML文件的数据进行解析</p>
<p><strong>分析：</strong></p>
<p>①下载Dom4j框架，官网下载。</p>
<p>②在项目中创建一个文件夹：lib</p>
<p>③将dom4j-2.1.1.jar文件复制到 lib 文件夹</p>
<p>④在jar文件上点右键，选择 Add as Library -&gt; 点击OK</p>
<p>⑤在类中导包使用</p>
<p><strong>Dom4j解析XML-得到Document对象</strong></p>
<p>SAXReader类</p>
<table>
<thead>
<tr class="header">
<th>构造器/方法</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>public SAXReader()</td>
<td>创建Dom4J的解析器对象</td>
</tr>
<tr class="even">
<td>Document read(String url)</td>
<td>加载XML文件成为Document对象</td>
</tr>
</tbody>
</table>
<p>Document类</p>
<table>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Element getRootElement()</td>
<td>获得根元素对象</td>
</tr>
</tbody>
</table>
<p><strong>Dom4j解析XML的元素、属性、文本</strong></p>
<table>
<colgroup>
<col style="width: 37%" />
<col style="width: 62%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>List<Element> elements()</td>
<td>得到当前元素下所有子元素</td>
</tr>
<tr class="even">
<td>List<Element> elements(String name)</td>
<td>得到当前元素下指定名字的子元素返回集合</td>
</tr>
<tr class="odd">
<td>Element element(String name)</td>
<td>得到当前元素下指定名字的子元素,如果有很多名字相同的返回第一个</td>
</tr>
<tr class="even">
<td>String getName()</td>
<td>得到元素名字</td>
</tr>
<tr class="odd">
<td>String attributeValue(String name)</td>
<td>通过属性名直接得到属性值</td>
</tr>
<tr class="even">
<td>String elementText(子元素名)</td>
<td>得到指定名称的子元素的文本</td>
</tr>
<tr class="odd">
<td>String getText()</td>
<td>得到文本</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   目标：学会使用dom4j解析XML文件中的数据。</span><br><span class="hljs-comment">    1、导入dom4j框架。</span><br><span class="hljs-comment">    2、准备一个XML文件。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Dom4JHelloWorldDemo1</span> &#123;<br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parseXMLData</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 1、创建一个Dom4j的解析器对象，代表了整个dom4j框架</span><br>        <span class="hljs-type">SAXReader</span> <span class="hljs-variable">saxReader</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SAXReader</span>();<br><br>        <span class="hljs-comment">// 2、把XML文件加载到内存中成为一个Document文档对象</span><br>        <span class="hljs-comment">// Document document = saxReader.read(new File(&quot;xml-app\\src\\Contacts.xml&quot;)); // 需要通过模块名去定位</span><br>        <span class="hljs-comment">// Document document = saxReader.read(new FileInputStream(&quot;xml-app\\src\\Contacts.xml&quot;));</span><br><br>        <span class="hljs-comment">// 注意: getResourceAsStream中的/是直接去src下寻找的文件</span><br>        <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> Dom4JHelloWorldDemo1.class.getResourceAsStream(<span class="hljs-string">&quot;/Contacts.xml&quot;</span>);<br>        <span class="hljs-type">Document</span> <span class="hljs-variable">document</span> <span class="hljs-operator">=</span> saxReader.read(is);<br><br>        <span class="hljs-comment">// 3、获取根元素对象</span><br>        <span class="hljs-type">Element</span> <span class="hljs-variable">root</span> <span class="hljs-operator">=</span> document.getRootElement();<br>        System.out.println(root.getName());<br><br>        <span class="hljs-comment">// 4、拿根元素下的全部子元素对象(一级)</span><br>        <span class="hljs-comment">// List&lt;Element&gt; sonEles =  root.elements();</span><br>        List&lt;Element&gt; sonEles =  root.elements(<span class="hljs-string">&quot;contact&quot;</span>);<br>        <span class="hljs-keyword">for</span> (Element sonEle : sonEles) &#123;<br>            System.out.println(sonEle.getName());<br>        &#125;<br><br>        <span class="hljs-comment">// 拿某个子元素</span><br>        <span class="hljs-type">Element</span> <span class="hljs-variable">userEle</span> <span class="hljs-operator">=</span> root.element(<span class="hljs-string">&quot;user&quot;</span>);<br>        System.out.println(userEle.getName());<br><br>        <span class="hljs-comment">// 默认提取第一个子元素对象 (Java语言。)</span><br>        <span class="hljs-type">Element</span> <span class="hljs-variable">contact</span> <span class="hljs-operator">=</span> root.element(<span class="hljs-string">&quot;contact&quot;</span>);<br>        <span class="hljs-comment">// 获取子元素文本</span><br>        System.out.println(contact.elementText(<span class="hljs-string">&quot;name&quot;</span>));<br>        <span class="hljs-comment">// 去掉前后空格</span><br>        System.out.println(contact.elementTextTrim(<span class="hljs-string">&quot;name&quot;</span>));<br>        <span class="hljs-comment">// 获取当前元素下的子元素对象</span><br>        <span class="hljs-type">Element</span> <span class="hljs-variable">email</span> <span class="hljs-operator">=</span> contact.element(<span class="hljs-string">&quot;email&quot;</span>);<br>        System.out.println(email.getText());<br>        <span class="hljs-comment">// 去掉前后空格</span><br>        System.out.println(email.getTextTrim());<br><br>        <span class="hljs-comment">// 根据元素获取属性值</span><br>        <span class="hljs-type">Attribute</span> <span class="hljs-variable">idAttr</span> <span class="hljs-operator">=</span> contact.attribute(<span class="hljs-string">&quot;id&quot;</span>);<br>        System.out.println(idAttr.getName() + <span class="hljs-string">&quot;--&gt;&quot;</span> + idAttr.getValue());<br>        <span class="hljs-comment">// 直接提取属性值</span><br>        System.out.println(contact.attributeValue(<span class="hljs-string">&quot;id&quot;</span>));<br>        System.out.println(contact.attributeValue(<span class="hljs-string">&quot;vip&quot;</span>));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>需求:利用Dom4J的知识，将Contact.xml文件中的联系人数据封装成List集合，其中每个元素是实体类Contact。打印输出
List 中的每个元素</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta">&lt;?xml version=<span class="hljs-string">&quot;1.0&quot;</span> encoding=<span class="hljs-string">&quot;UTF-8&quot;</span>?&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">contactList</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">contact</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;1&quot;</span> <span class="hljs-attr">vip</span>=<span class="hljs-string">&quot;true&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>   潘金莲  <span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">gender</span>&gt;</span>女<span class="hljs-tag">&lt;/<span class="hljs-name">gender</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">email</span>&gt;</span>panpan@itcast.cn<span class="hljs-tag">&lt;/<span class="hljs-name">email</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">contact</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">contact</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;2&quot;</span> <span class="hljs-attr">vip</span>=<span class="hljs-string">&quot;false&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>武松<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">gender</span>&gt;</span>男<span class="hljs-tag">&lt;/<span class="hljs-name">gender</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">email</span>&gt;</span>wusong@itcast.cn<span class="hljs-tag">&lt;/<span class="hljs-name">email</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">contact</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">contact</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;3&quot;</span> <span class="hljs-attr">vip</span>=<span class="hljs-string">&quot;false&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>武大狼<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">gender</span>&gt;</span>男<span class="hljs-tag">&lt;/<span class="hljs-name">gender</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">email</span>&gt;</span>wuda@itcast.cn<span class="hljs-tag">&lt;/<span class="hljs-name">email</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">contact</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">user</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">user</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">contactList</span>&gt;</span><br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> &lt;contact id=&quot;1&quot; vip=&quot;true&quot;&gt;</span><br><span class="hljs-comment"> &lt;name&gt;   潘金莲  &lt;/name&gt;</span><br><span class="hljs-comment"> &lt;gender&gt;女&lt;/gender&gt;</span><br><span class="hljs-comment"> &lt;email&gt;panpan@itcast.cn&lt;/email&gt;</span><br><span class="hljs-comment"> &lt;/contact&gt;</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Contact</span> &#123;<br>    <span class="hljs-keyword">private</span> String name;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> id;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">boolean</span> vip;<br>    <span class="hljs-keyword">private</span> <span class="hljs-type">char</span> gender;<br>    <span class="hljs-keyword">private</span> String email;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Contact</span><span class="hljs-params">()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">Contact</span><span class="hljs-params">(String name, <span class="hljs-type">int</span> id, <span class="hljs-type">boolean</span> vip, <span class="hljs-type">char</span> gendar, String email)</span> &#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>        <span class="hljs-built_in">this</span>.id = id;<br>        <span class="hljs-built_in">this</span>.vip = vip;<br>        <span class="hljs-built_in">this</span>.gender = gendar;<br>        <span class="hljs-built_in">this</span>.email = email;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getName</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> name;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setName</span><span class="hljs-params">(String name)</span> &#123;<br>        <span class="hljs-built_in">this</span>.name = name;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">getId</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> id;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setId</span><span class="hljs-params">(<span class="hljs-type">int</span> id)</span> &#123;<br>        <span class="hljs-built_in">this</span>.id = id;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">boolean</span> <span class="hljs-title function_">isVip</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> vip;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setVip</span><span class="hljs-params">(<span class="hljs-type">boolean</span> vip)</span> &#123;<br>        <span class="hljs-built_in">this</span>.vip = vip;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">char</span> <span class="hljs-title function_">getGender</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> gender;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setGender</span><span class="hljs-params">(<span class="hljs-type">char</span> gender)</span> &#123;<br>        <span class="hljs-built_in">this</span>.gender = gender;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">getEmail</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> email;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setEmail</span><span class="hljs-params">(String email)</span> &#123;<br>        <span class="hljs-built_in">this</span>.email = email;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> String <span class="hljs-title function_">toString</span><span class="hljs-params">()</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;Contact&#123;&quot;</span> +<br>                <span class="hljs-string">&quot;name=&#x27;&quot;</span> + name + <span class="hljs-string">&#x27;\&#x27;&#x27;</span> +<br>                <span class="hljs-string">&quot;, id=&quot;</span> + id +<br>                <span class="hljs-string">&quot;, vip=&quot;</span> + vip +<br>                <span class="hljs-string">&quot;, gendar=&quot;</span> + gender +<br>                <span class="hljs-string">&quot;, email=&#x27;&quot;</span> + email + <span class="hljs-string">&#x27;\&#x27;&#x27;</span> +<br>                <span class="hljs-string">&#x27;&#125;&#x27;</span>;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Dom4JTest2</span> &#123;<br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parseToList</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// 需求：解析XML中的数据成为一个List集合对象。</span><br>        <span class="hljs-comment">// 1、导入框架（做过）</span><br>        <span class="hljs-comment">// 2、创建SaxReader对象</span><br>        <span class="hljs-type">SAXReader</span> <span class="hljs-variable">saxReader</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SAXReader</span>();<br>        <span class="hljs-comment">// 3、加载XML文件成为文档对象Document对象。</span><br>        <span class="hljs-type">Document</span> <span class="hljs-variable">document</span> <span class="hljs-operator">=</span><br>                saxReader.read(Dom4JTest2.class.getResourceAsStream(<span class="hljs-string">&quot;/Contacts.xml&quot;</span>));<br>        <span class="hljs-comment">// 4、先拿根元素</span><br>        <span class="hljs-type">Element</span> <span class="hljs-variable">root</span> <span class="hljs-operator">=</span> document.getRootElement();<br>        <span class="hljs-comment">// 5、提取contact子元素</span><br>        List&lt;Element&gt; contactEles = root.elements(<span class="hljs-string">&quot;contact&quot;</span>);<br>        <span class="hljs-comment">// 6、准备一个ArrayList集合封装联系人信息</span><br>        List&lt;Contact&gt; contacts = <span class="hljs-keyword">new</span> <span class="hljs-title class_">ArrayList</span>&lt;&gt;();<br>        <span class="hljs-comment">// 7、遍历Contact子元素</span><br>        <span class="hljs-keyword">for</span> (Element contactEle : contactEles) &#123;<br>            <span class="hljs-comment">// 8、每个子元素都是一个联系人对象</span><br>            <span class="hljs-type">Contact</span> <span class="hljs-variable">contact</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Contact</span>();<br>            contact.setId(Integer.valueOf(contactEle.attributeValue(<span class="hljs-string">&quot;id&quot;</span>)));<br>            contact.setVip(Boolean.valueOf(contactEle.attributeValue(<span class="hljs-string">&quot;vip&quot;</span>)));<br>            contact.setName(contactEle.elementTextTrim(<span class="hljs-string">&quot;name&quot;</span>));<br>            contact.setGender(contactEle.elementTextTrim(<span class="hljs-string">&quot;gender&quot;</span>).charAt(<span class="hljs-number">0</span>));<br>            contact.setEmail(contactEle.elementText(<span class="hljs-string">&quot;email&quot;</span>));<br>            <span class="hljs-comment">// 9、把联系人对象数据加入到List集合</span><br>            contacts.add(contact);<br>        &#125;<br>        <span class="hljs-comment">// 10、遍历List集合</span><br>        <span class="hljs-keyword">for</span> (Contact contact : contacts) &#123;<br>            System.out.println(contact);<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<p>如果需要从XML文件中检索需要的某个信息（如name）怎么解决？</p>
<p><strong>Dom4j需要进行文件的全部解析，然后再寻找数据。</strong></p>
<p><strong>Xpath技术更加适合做信息检索。</strong></p>
<h6 id="xpath介绍"><strong>XPath介绍</strong></h6>
<p>XPath在解析XML文档方面提供了一独树一帜的路径思想，更加优雅，高效</p>
<p>XPath使用路径表达式来定位XML文档中的元素节点或属性节点。</p>
<p>/元素/子元素/孙元素</p>
<p>//子元素//孙元素</p>
<h6
id="需求使用dom4j把一个xml文件的数据进行解析">需求：使用Dom4J把一个XML文件的数据进行解析</h6>
<p>分析：</p>
<p>①导入jar包(dom4j和jaxen-1.1.2.jar)，Xpath技术依赖Dom4j技术</p>
<p>②通过dom4j的SAXReader获取Document对象</p>
<p>③利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作。</p>
<p>④Document中与Xpath相关的API如下：</p>
<table>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Node selectSingleNode("表达式")</td>
<td>获取符合表达式的唯一元素</td>
</tr>
<tr class="even">
<td>List<Node> selectNodes("表达式")</td>
<td>获取符合表达式的元素集合</td>
</tr>
</tbody>
</table>
<h6 id="xpath的四大检索方案"><strong>Xpath的四大检索方案</strong></h6>
<p>绝对路径</p>
<p>相对路径</p>
<p>全文检索</p>
<p>属性查找</p>
<h6 id="xpath绝对路径"><strong>XPath：绝对路径</strong></h6>
<p>采用绝对路径获取从根节点开始逐层的查找/contactList/contact/name节点列表并打印信息</p>
<table>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>/根元素/子元素/孙元素</td>
<td>从根元素开始，一级一级向下查找，不能跨级</td>
</tr>
</tbody>
</table>
<h6 id="xpath相对路径"><strong>XPath：相对路径</strong></h6>
<p>先得到根节点contactList</p>
<p>再采用相对路径获取下一级contact 节点的name子节点并打印信息</p>
<table>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>./子元素/孙元素</td>
<td>从当前元素开始，一级一级向下查找，不能跨级</td>
</tr>
</tbody>
</table>
<h6 id="xpath全文搜索"><strong>XPath：全文搜索</strong></h6>
<p>直接全文搜索所有的name元素并打印</p>
<table>
<colgroup>
<col style="width: 20%" />
<col style="width: 79%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>//contact</td>
<td>找contact元素，无论元素在哪里</td>
</tr>
<tr class="even">
<td>//contact/name</td>
<td>找contact，无论在哪一级，但name一定是contact的子节点</td>
</tr>
<tr class="odd">
<td>//contact//name</td>
<td>contact无论在哪一种，name只要是contact的子孙元素都可以找到</td>
</tr>
</tbody>
</table>
<h6 id="xpath属性查找"><strong>XPath：属性查找</strong></h6>
<p>在全文中搜索属性，或者带属性的元素</p>
<table>
<colgroup>
<col style="width: 27%" />
<col style="width: 72%" />
</colgroup>
<thead>
<tr class="header">
<th>方法名</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>//<span class="citation" data-cites="属性名">@属性名</span></td>
<td>查找属性对象，无论是哪个元素，只要有这个属性即可。</td>
</tr>
<tr class="even">
<td>//元素<span class="citation"
data-cites="属性名">[@属性名]</span></td>
<td>查找元素对象，全文搜索指定元素名和属性名。</td>
</tr>
<tr class="odd">
<td>//元素//<span class="citation"
data-cites="属性名">[@属性名=‘值’]</span></td>
<td>查找元素对象，全文搜索指定元素名和属性名，并且属性值相等。</td>
</tr>
</tbody>
</table>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：XPath检索XML中的信息啊。(了解)</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    引入：</span><br><span class="hljs-comment">        Dom4J可以用于解析整个XML的数据。</span><br><span class="hljs-comment">        但是如果要检索XML中的某些信息，建议使用XPath.（Xpath依赖Dom4j技术）</span><br><span class="hljs-comment">        Dom4J用于解析数据，Xpath用于检索数据。</span><br><span class="hljs-comment">    XPath使用步骤：</span><br><span class="hljs-comment">        1.导入dom4j框架。（XPath依赖于Dom4j技术,必须先导入dom4j框架！）</span><br><span class="hljs-comment">        2.导入XPath独有的框架包。jaxen-1.1.2.jar</span><br><span class="hljs-comment">    XPath常用API:</span><br><span class="hljs-comment">        List&lt;Node&gt; selectNodes(String var1):检索出一批节点集合。</span><br><span class="hljs-comment">        Node selectSingleNode(String var1)：检索出一个节点返回。</span><br><span class="hljs-comment">    XPath提供的四种检索数据的写法：</span><br><span class="hljs-comment">        1.绝对路径。</span><br><span class="hljs-comment">        2.相对路径。</span><br><span class="hljs-comment">        3.全文搜索。</span><br><span class="hljs-comment">        4.属性查找。</span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">         1.绝对路径： /根元素/子元素/子元素。</span><br><span class="hljs-comment">         2.相对路径： ./子元素/子元素。 (.代表了当前元素)</span><br><span class="hljs-comment">         3.全文搜索：</span><br><span class="hljs-comment">                //元素  在全文找这个元素</span><br><span class="hljs-comment">                //元素1/元素2  在全文找元素1下面的一级元素2</span><br><span class="hljs-comment">                //元素1//元素2  在全文找元素1下面的全部元素2</span><br><span class="hljs-comment">         4.属性查找。</span><br><span class="hljs-comment">                //@属性名称  在全文检索属性对象。</span><br><span class="hljs-comment">                //元素[@属性名称]  在全文检索包含该属性的元素对象。</span><br><span class="hljs-comment">                //元素[@属性名称=值]  在全文检索包含该属性的元素且属性值为该值的元素对象。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">XPathDemo</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     1.绝对路径: /根元素/子元素/子元素。</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parse01</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a、创建解析器对象</span><br>        <span class="hljs-type">SAXReader</span> <span class="hljs-variable">saxReader</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SAXReader</span>();<br>        <span class="hljs-comment">// b、把XML加载成Document文档对象</span><br>        <span class="hljs-type">Document</span> <span class="hljs-variable">document</span> <span class="hljs-operator">=</span><br>                saxReader.read(XPathDemo.class.getResourceAsStream(<span class="hljs-string">&quot;/Contacts2.xml&quot;</span>));<br>        <span class="hljs-comment">// c、检索全部的名称</span><br>        List&lt;Node&gt; nameNodes = document.selectNodes(<span class="hljs-string">&quot;/contactList/contact/name&quot;</span>);<br>        <span class="hljs-keyword">for</span> (Node nameNode : nameNodes) &#123;<br>            <span class="hljs-type">Element</span>  <span class="hljs-variable">nameEle</span> <span class="hljs-operator">=</span> (Element) nameNode;<br>            System.out.println(nameEle.getTextTrim());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     2.相对路径： ./子元素/子元素。 (.代表了当前元素)</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parse02</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a、创建解析器对象</span><br>        <span class="hljs-type">SAXReader</span> <span class="hljs-variable">saxReader</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SAXReader</span>();<br>        <span class="hljs-comment">// b、把XML加载成Document文档对象</span><br>        <span class="hljs-type">Document</span> <span class="hljs-variable">document</span> <span class="hljs-operator">=</span><br>                saxReader.read(XPathDemo.class.getResourceAsStream(<span class="hljs-string">&quot;/Contacts2.xml&quot;</span>));<br>        <span class="hljs-type">Element</span> <span class="hljs-variable">root</span> <span class="hljs-operator">=</span> document.getRootElement();<br>        <span class="hljs-comment">// c、检索全部的名称</span><br>        List&lt;Node&gt; nameNodes = root.selectNodes(<span class="hljs-string">&quot;./contact/name&quot;</span>);<br>        <span class="hljs-keyword">for</span> (Node nameNode : nameNodes) &#123;<br>            <span class="hljs-type">Element</span>  <span class="hljs-variable">nameEle</span> <span class="hljs-operator">=</span> (Element) nameNode;<br>            System.out.println(nameEle.getTextTrim());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     3.全文搜索：</span><br><span class="hljs-comment">     //元素  在全文找这个元素</span><br><span class="hljs-comment">     //元素1/元素2  在全文找元素1下面的一级元素2</span><br><span class="hljs-comment">     //元素1//元素2  在全文找元素1下面的全部元素2</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parse03</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a、创建解析器对象</span><br>        <span class="hljs-type">SAXReader</span> <span class="hljs-variable">saxReader</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SAXReader</span>();<br>        <span class="hljs-comment">// b、把XML加载成Document文档对象</span><br>        <span class="hljs-type">Document</span> <span class="hljs-variable">document</span> <span class="hljs-operator">=</span><br>                saxReader.read(XPathDemo.class.getResourceAsStream(<span class="hljs-string">&quot;/Contacts2.xml&quot;</span>));<br>        <span class="hljs-comment">// c、检索数据</span><br>        <span class="hljs-comment">//List&lt;Node&gt; nameNodes = document.selectNodes(&quot;//name&quot;);</span><br>        <span class="hljs-comment">// List&lt;Node&gt; nameNodes = document.selectNodes(&quot;//contact/name&quot;);</span><br>        List&lt;Node&gt; nameNodes = document.selectNodes(<span class="hljs-string">&quot;//contact//name&quot;</span>);<br>        <span class="hljs-keyword">for</span> (Node nameNode : nameNodes) &#123;<br>            <span class="hljs-type">Element</span>  <span class="hljs-variable">nameEle</span> <span class="hljs-operator">=</span> (Element) nameNode;<br>            System.out.println(nameEle.getTextTrim());<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">     4.属性查找。</span><br><span class="hljs-comment">     //@属性名称  在全文检索属性对象。</span><br><span class="hljs-comment">     //元素[@属性名称]  在全文检索包含该属性的元素对象。</span><br><span class="hljs-comment">     //元素[@属性名称=值]  在全文检索包含该属性的元素且属性值为该值的元素对象。</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-meta">@Test</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">parse04</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> Exception &#123;<br>        <span class="hljs-comment">// a、创建解析器对象</span><br>        <span class="hljs-type">SAXReader</span> <span class="hljs-variable">saxReader</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">SAXReader</span>();<br>        <span class="hljs-comment">// b、把XML加载成Document文档对象</span><br>        <span class="hljs-type">Document</span> <span class="hljs-variable">document</span> <span class="hljs-operator">=</span><br>                saxReader.read(XPathDemo.class.getResourceAsStream(<span class="hljs-string">&quot;/Contacts2.xml&quot;</span>));<br>        <span class="hljs-comment">// c、检索数据</span><br>        List&lt;Node&gt; nodes = document.selectNodes(<span class="hljs-string">&quot;//@id&quot;</span>);<br>        <span class="hljs-keyword">for</span> (Node node : nodes) &#123;<br>            <span class="hljs-type">Attribute</span> <span class="hljs-variable">attr</span> <span class="hljs-operator">=</span> (Attribute) node;<br>            System.out.println(attr.getName() + <span class="hljs-string">&quot;===&gt;&quot;</span> + attr.getValue());<br>        &#125;<br><br>        <span class="hljs-comment">// 查询name元素（包含id属性的）</span><br><span class="hljs-comment">//      Node node = document.selectSingleNode(&quot;//name[@id]&quot;);</span><br>        <span class="hljs-type">Node</span> <span class="hljs-variable">node</span> <span class="hljs-operator">=</span> document.selectSingleNode(<span class="hljs-string">&quot;//name[@id=888]&quot;</span>);<br>        <span class="hljs-type">Element</span> <span class="hljs-variable">ele</span> <span class="hljs-operator">=</span> (Element) node;<br>        System.out.println(ele.getTextTrim());<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h5 id="设计模式-1">设计模式</h5>
<h6 id="什么是工厂设计模式"><strong>什么是工厂设计模式？</strong></h6>
<ul>
<li><p>之前我们创建类对象时, 都是使用new
对象的形式创建,在很多业务场景下也提供了不直接new的方式 。</p></li>
<li><p>工厂模式（Factory Pattern）是 Java 中最常用的设计模式之一，
这种类型的设计模式属于创建型模式，它提供了一种获取对象的方式。</p></li>
</ul>
<h6 id="工厂设计模式的作用"><strong>工厂设计模式的作用：</strong></h6>
<p>工厂的方法可以封装对象的创建细节，比如：为该对象进行加工和数据注入。</p>
<p>可以实现类与类之间的解耦操作（核心思想）。（不想用了只需要改名字）</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FactoryPattern</span> &#123;<br>    <span class="hljs-comment">/**</span><br><span class="hljs-comment">       定义一个方法，创建对象返回</span><br><span class="hljs-comment">     */</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Computer <span class="hljs-title function_">createComputer</span><span class="hljs-params">(String info)</span>&#123;<br>        <span class="hljs-keyword">switch</span> (info)&#123;<br>            <span class="hljs-keyword">case</span> <span class="hljs-string">&quot;huawei&quot;</span>:<br>                <span class="hljs-type">Computer</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Huawei</span>();<br>                c.setName(<span class="hljs-string">&quot;huawei pro 16&quot;</span>);<br>                c.setPrice(<span class="hljs-number">5999</span>);<br>                <span class="hljs-keyword">return</span> c;<br>            <span class="hljs-keyword">case</span> <span class="hljs-string">&quot;mac&quot;</span>:<br>                <span class="hljs-type">Computer</span> <span class="hljs-variable">c2</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Mac</span>();<br>                c2.setName(<span class="hljs-string">&quot;MacBook pro&quot;</span>);<br>                c2.setPrice(<span class="hljs-number">11999</span>);<br>                <span class="hljs-keyword">return</span> c2;<br>            <span class="hljs-keyword">default</span>:<br>                <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">    目标：工厂模式。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    什么是工厂设计模式？</span><br><span class="hljs-comment">            工厂模式（Factory Pattern）是 Java 中最常用的设计模式之一。</span><br><span class="hljs-comment">            这种类型的设计模式属于创建型模式，它提供了一种创建对象的方式。</span><br><span class="hljs-comment">            之前我们创建类对象时, 都是使用new 对象的形式创建, 除new 对象方式以外,</span><br><span class="hljs-comment">            工厂模式也可以创建对象。</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    工厂设计模式的作用：</span><br><span class="hljs-comment">            1.对象通过工厂的方法创建返回，工厂的方法可以为该对象进行加工和数据注入。</span><br><span class="hljs-comment">            2.可以实现类与类之间的解耦操作（核心思想，重点）</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    小结：</span><br><span class="hljs-comment">        工厂模式的思想是提供一个工厂方法返回对象！</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FactoryDemo</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">Computer</span> <span class="hljs-variable">c1</span> <span class="hljs-operator">=</span> FactoryPattern.createComputer(<span class="hljs-string">&quot;huawei&quot;</span>);<br>        c1.start();<br><br>        <span class="hljs-type">Computer</span> <span class="hljs-variable">c2</span> <span class="hljs-operator">=</span> FactoryPattern.createComputer(<span class="hljs-string">&quot;mac&quot;</span>);<br>        c2.start();<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>
<h6 id="什么是装饰设计模式"><strong>什么是装饰设计模式？</strong></h6>
<ul>
<li>创建一个新类，包装原始类，从而在新类中提升原来类的功能。</li>
</ul>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-function"><span class="hljs-title">InputStream</span><span class="hljs-params">(抽象父类)</span></span><br><span class="hljs-function"><span class="hljs-title">FileInputStream</span><span class="hljs-params">(实现子类，读写性能较差)</span></span><br><span class="hljs-function"><span class="hljs-title">BufferedInputStream</span><span class="hljs-params">(实现子类，装饰类，读写性能高)</span></span><br></code></pre></td></tr></table></figure>
<ul>
<li><p>定义父类。</p></li>
<li><p>定义原始类，继承父类，定义功能。</p></li>
<li><p>定义装饰类，继承父类，包装原始类，增强功能！！</p></li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment">   共同父类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InputStream</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-type">int</span> <span class="hljs-title function_">read</span><span class="hljs-params">()</span>;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-type">int</span> <span class="hljs-title function_">read</span><span class="hljs-params">(<span class="hljs-type">byte</span>[] buffer)</span>;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">   原始类</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">FileInputStream</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">InputStream</span>&#123;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">read</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;低性能的方式读取了一个字节a&quot;</span>);<br>        <span class="hljs-keyword">return</span> <span class="hljs-number">97</span>;<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">read</span><span class="hljs-params">(<span class="hljs-type">byte</span>[] buffer)</span> &#123;<br>        buffer[<span class="hljs-number">0</span>] = <span class="hljs-number">97</span>;<br>        buffer[<span class="hljs-number">1</span>] = <span class="hljs-number">98</span>;<br>        buffer[<span class="hljs-number">2</span>] = <span class="hljs-number">99</span>;<br>        System.out.println(<span class="hljs-string">&quot;低性能的方式读取了一个字节数组：&quot;</span> + Arrays.toString(buffer));<br>        <span class="hljs-keyword">return</span> <span class="hljs-number">3</span>;<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">   装饰类：继承InputStream 拓展原始类的功能</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BufferedInputStream</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">InputStream</span>&#123;<br>    <span class="hljs-keyword">private</span> InputStream is;<br>    <span class="hljs-keyword">public</span> <span class="hljs-title function_">BufferedInputStream</span><span class="hljs-params">(InputStream is)</span>&#123;<br>        <span class="hljs-built_in">this</span>.is = is;<br>    &#125;<br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">read</span><span class="hljs-params">()</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;提供8KB的缓冲区，提高读数据性能~~~~&quot;</span>);<br>        <span class="hljs-keyword">return</span> is.read();<br>    &#125;<br><br>    <span class="hljs-meta">@Override</span><br>    <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">read</span><span class="hljs-params">(<span class="hljs-type">byte</span>[] buffer)</span> &#123;<br>        System.out.println(<span class="hljs-string">&quot;提供8KB的缓冲区，提高读数据性能~~~~&quot;</span>);<br>        <span class="hljs-keyword">return</span> is.read(buffer);<br>    &#125;<br>&#125;<br><br><br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment">  装饰模式</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">    定义父类：InputStream</span><br><span class="hljs-comment">    定义实现类：FileInputStream 继续父类 定义功能</span><br><span class="hljs-comment">    定义装饰实现类：BufferedInputStream 继承父类 定义功能 包装原始类，增强功能。</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">DecoratorPattern</span> &#123;<br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> &#123;<br>        <span class="hljs-type">InputStream</span> <span class="hljs-variable">is</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BufferedInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>());<br>        System.out.println(is.read());<br>        System.out.println(is.read(<span class="hljs-keyword">new</span> <span class="hljs-title class_">byte</span>[<span class="hljs-number">3</span>]));<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/java/">java</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/%E5%9F%BA%E7%A1%80/">基础</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2022/05/05/mysql%E5%9F%BA%E7%A1%80/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">mysql基础</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  <script  src="/js/local-search.js" ></script>



  
    <script  src="/js/img-lazyload.js" ></script>
  



  



  
    <script  src="https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4/anchor.min.js" ></script>
  
  
    <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js" ></script>
  






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
        typing(title);
      
    })(window, document);
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>


<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"/live2dw/assets/assets/Epsilon2.1.model.json"},"display":{"position":"top","width":300,"height":600,"hOffset":-10,"vOffset":0},"mobile":{"show":true},"react":{"opacity":0.7},"post":{"math":{"enable":true,"specific":true,"engine":"mathjax"}},"log":false});</script></body>
</html>
